summaryrefslogtreecommitdiff
path: root/src/libstrongswan/crypto
diff options
context:
space:
mode:
authorRene Mayrhofer <rene@mayrhofer.eu.org>2008-07-10 12:47:56 +0000
committerRene Mayrhofer <rene@mayrhofer.eu.org>2008-07-10 12:47:56 +0000
commiteb841c5ef668a48782ef1154fda65cb6048f5885 (patch)
tree00dd0cb4313bf2291d94ed511fe51f0b4bc7ea7a /src/libstrongswan/crypto
parent738206039047924ae7e4762a53d121be1ca43000 (diff)
downloadvyos-strongswan-eb841c5ef668a48782ef1154fda65cb6048f5885.tar.gz
vyos-strongswan-eb841c5ef668a48782ef1154fda65cb6048f5885.zip
- Updated to new upstream.
Diffstat (limited to 'src/libstrongswan/crypto')
-rw-r--r--src/libstrongswan/crypto/ac.c636
-rw-r--r--src/libstrongswan/crypto/ac.h110
-rw-r--r--src/libstrongswan/crypto/ca.c813
-rw-r--r--src/libstrongswan/crypto/ca.h243
-rw-r--r--src/libstrongswan/crypto/certinfo.c257
-rw-r--r--src/libstrongswan/crypto/certinfo.h203
-rwxr-xr-xsrc/libstrongswan/crypto/crl.c536
-rwxr-xr-xsrc/libstrongswan/crypto/crl.h158
-rw-r--r--src/libstrongswan/crypto/crypters/aes_cbc_crypter.c1620
-rw-r--r--src/libstrongswan/crypto/crypters/aes_cbc_crypter.h61
-rw-r--r--src/libstrongswan/crypto/crypters/crypter.c47
-rw-r--r--src/libstrongswan/crypto/crypters/crypter.h121
-rw-r--r--src/libstrongswan/crypto/crypters/des_crypter.c1536
-rw-r--r--src/libstrongswan/crypto/crypters/des_crypter.h58
-rw-r--r--src/libstrongswan/crypto/crypto_factory.c571
-rw-r--r--src/libstrongswan/crypto/crypto_factory.h235
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.c573
-rw-r--r--src/libstrongswan/crypto/diffie_hellman.h85
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.c64
-rw-r--r--src/libstrongswan/crypto/hashers/hasher.h140
-rw-r--r--src/libstrongswan/crypto/hashers/md5_hasher.c405
-rw-r--r--src/libstrongswan/crypto/hashers/md5_hasher.h60
-rw-r--r--src/libstrongswan/crypto/hashers/sha1_hasher.c280
-rw-r--r--src/libstrongswan/crypto/hashers/sha1_hasher.h60
-rw-r--r--src/libstrongswan/crypto/hashers/sha2_hasher.c672
-rw-r--r--src/libstrongswan/crypto/hashers/sha2_hasher.h62
-rw-r--r--src/libstrongswan/crypto/hmac.c215
-rw-r--r--src/libstrongswan/crypto/hmac.h117
-rw-r--r--src/libstrongswan/crypto/ietf_attr_list.c405
-rw-r--r--src/libstrongswan/crypto/ietf_attr_list.h89
-rw-r--r--src/libstrongswan/crypto/ocsp.c934
-rw-r--r--src/libstrongswan/crypto/ocsp.h89
-rw-r--r--src/libstrongswan/crypto/pkcs7.c1077
-rw-r--r--src/libstrongswan/crypto/pkcs7.h209
-rw-r--r--src/libstrongswan/crypto/pkcs9.c82
-rw-r--r--src/libstrongswan/crypto/pkcs9.h63
-rw-r--r--src/libstrongswan/crypto/prf_plus.c9
-rw-r--r--src/libstrongswan/crypto/prf_plus.h46
-rw-r--r--src/libstrongswan/crypto/prfs/fips_prf.c258
-rw-r--r--src/libstrongswan/crypto/prfs/fips_prf.h80
-rw-r--r--src/libstrongswan/crypto/prfs/hmac_prf.c118
-rw-r--r--src/libstrongswan/crypto/prfs/hmac_prf.h65
-rw-r--r--src/libstrongswan/crypto/prfs/prf.c47
-rw-r--r--src/libstrongswan/crypto/prfs/prf.h82
-rw-r--r--src/libstrongswan/crypto/rngs/rng.c24
-rw-r--r--src/libstrongswan/crypto/rngs/rng.h75
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_private_key.c722
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_private_key.h163
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_public_key.c516
-rw-r--r--src/libstrongswan/crypto/rsa/rsa_public_key.h173
-rw-r--r--src/libstrongswan/crypto/signers/hmac_signer.c185
-rw-r--r--src/libstrongswan/crypto/signers/hmac_signer.h68
-rw-r--r--src/libstrongswan/crypto/signers/signer.c34
-rw-r--r--src/libstrongswan/crypto/signers/signer.h84
-rwxr-xr-xsrc/libstrongswan/crypto/x509.c1562
-rwxr-xr-xsrc/libstrongswan/crypto/x509.h406
56 files changed, 1194 insertions, 16409 deletions
diff --git a/src/libstrongswan/crypto/ac.c b/src/libstrongswan/crypto/ac.c
deleted file mode 100644
index 641ce5d64..000000000
--- a/src/libstrongswan/crypto/ac.c
+++ /dev/null
@@ -1,636 +0,0 @@
-/**
- * @file ac.c
- *
- * @brief Implementation of x509ac_t.
- *
- */
-
-/*
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2007 Andreas Steffen, Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: ac.c 3355 2007-11-20 12:06:40Z martin $
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include <library.h>
-#include <debug.h>
-
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <crypto/x509.h>
-#include <crypto/ietf_attr_list.h>
-#include <utils/identification.h>
-#include <utils/linked_list.h>
-#include <utils/lexparser.h>
-
-#include "ac.h"
-
-#define ACERT_WARNING_INTERVAL 1 /* day */
-
-typedef struct private_x509ac_t private_x509ac_t;
-
-/**
- * Private data of a x509ac_t object.
- */
-struct private_x509ac_t {
- /**
- * Public interface for this attribute certificate.
- */
- x509ac_t public;
-
- /**
- * Time when attribute certificate was installed
- */
- time_t installed;
-
- /**
- * X.509 attribute certificate in DER format
- */
- chunk_t certificate;
-
- /**
- * X.509 attribute certificate body over which signature is computed
- */
- chunk_t certificateInfo;
-
- /**
- * Version of the X.509 attribute certificate
- */
- u_int version;
-
- /**
- * Serial number of the X.509 attribute certificate
- */
- chunk_t serialNumber;
-
- /**
- * ID representing the issuer of the holder certificate
- */
- identification_t *holderIssuer;
-
- /**
- * Serial number of the holder certificate
- */
- chunk_t holderSerial;
-
- /**
- * ID representing the holder
- */
- identification_t *entityName;
-
- /**
- * ID representing the attribute certificate issuer
- */
- identification_t *issuerName;
-
- /**
- * Signature algorithm
- */
- int sigAlg;
-
- /**
- * Start time of certificate validity
- */
- time_t notBefore;
-
- /**
- * End time of certificate validity
- */
- time_t notAfter;
-
- /**
- * List of charging attributes
- */
- linked_list_t *charging;
-
- /**
- * List of groub attributes
- */
- linked_list_t *groups;
-
- /**
- * Authority Key Identifier
- */
- chunk_t authKeyID;
-
- /**
- * Authority Key Serial Number
- */
- chunk_t authKeySerialNumber;
-
- /**
- * No revocation information available
- */
- bool noRevAvail;
-
- /**
- * Signature algorithm (must be identical to sigAlg)
- */
- int algorithm;
-
- /**
- * Signature
- */
- chunk_t signature;
-};
-
-/**
- * ASN.1 definition of roleSyntax
- */
-static const asn1Object_t roleSyntaxObjects[] =
-{
- { 0, "roleSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "roleAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_OBJ }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
- { 1, "roleName", ASN1_CONTEXT_C_1, ASN1_OBJ } /* 3 */
-};
-
-#define ROLE_ROOF 4
-
-/**
- * ASN.1 definition of an X509 attribute certificate
- */
-static const asn1Object_t acObjects[] =
-{
- { 0, "AttributeCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "AttributeCertificateInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "version", ASN1_INTEGER, ASN1_DEF |
- ASN1_BODY }, /* 2 */
- { 2, "holder", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
- { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 4 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 6 */
- { 4, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
- ASN1_BODY }, /* 7 */
- { 4, "end opt", ASN1_EOC, ASN1_END }, /* 8 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
- { 3, "entityName", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_OBJ }, /* 10 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
- { 3, "objectDigestInfo", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 12 */
- { 4, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 13*/
- { 4, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
- ASN1_BODY }, /* 14 */
- { 4, "end opt", ASN1_EOC, ASN1_END }, /* 15*/
- { 4, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 16 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 17 */
- { 2, "v2Form", ASN1_CONTEXT_C_0, ASN1_NONE }, /* 18 */
- { 3, "issuerName", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_OBJ }, /* 19 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
- { 3, "baseCertificateID", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 21 */
- { 4, "issuerSerial", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
- { 5, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 23 */
- { 5, "serial", ASN1_INTEGER, ASN1_BODY }, /* 24 */
- { 5, "issuerUID", ASN1_BIT_STRING, ASN1_OPT |
- ASN1_BODY }, /* 25 */
- { 5, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 27 */
- { 3, "objectDigestInfo", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 28 */
- { 4, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 29 */
- { 5, "digestedObjectType", ASN1_ENUMERATED, ASN1_BODY }, /* 30 */
- { 5, "otherObjectTypeID", ASN1_OID, ASN1_OPT |
- ASN1_BODY }, /* 31 */
- { 5, "end opt", ASN1_EOC, ASN1_END }, /* 32 */
- { 5, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 33 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 34 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 35 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 36 */
- { 2, "attrCertValidityPeriod", ASN1_SEQUENCE, ASN1_NONE }, /* 37 */
- { 3, "notBeforeTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 38 */
- { 3, "notAfterTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 39 */
- { 2, "attributes", ASN1_SEQUENCE, ASN1_LOOP }, /* 40 */
- { 3, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 41 */
- { 4, "type", ASN1_OID, ASN1_BODY }, /* 42 */
- { 4, "values", ASN1_SET, ASN1_LOOP }, /* 43 */
- { 5, "value", ASN1_EOC, ASN1_RAW }, /* 44 */
- { 4, "end loop", ASN1_EOC, ASN1_END }, /* 45 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 46 */
- { 2, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 47 */
- { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 48 */
- { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 49 */
- { 4, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 50 */
- { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 51 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 52 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 53 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 54 */
-};
-
-#define AC_OBJ_CERTIFICATE 0
-#define AC_OBJ_CERTIFICATE_INFO 1
-#define AC_OBJ_VERSION 2
-#define AC_OBJ_HOLDER_ISSUER 5
-#define AC_OBJ_HOLDER_SERIAL 6
-#define AC_OBJ_ENTITY_NAME 10
-#define AC_OBJ_ISSUER_NAME 19
-#define AC_OBJ_ISSUER 23
-#define AC_OBJ_SIG_ALG 35
-#define AC_OBJ_SERIAL_NUMBER 36
-#define AC_OBJ_NOT_BEFORE 38
-#define AC_OBJ_NOT_AFTER 39
-#define AC_OBJ_ATTRIBUTE_TYPE 42
-#define AC_OBJ_ATTRIBUTE_VALUE 44
-#define AC_OBJ_EXTN_ID 49
-#define AC_OBJ_CRITICAL 50
-#define AC_OBJ_EXTN_VALUE 51
-#define AC_OBJ_ALGORITHM 53
-#define AC_OBJ_SIGNATURE 54
-#define AC_OBJ_ROOF 55
-
-/**
- * Implements x509ac_t.is_valid
- */
-static err_t is_valid(const private_x509ac_t *this, time_t *until)
-{
- time_t current_time = time(NULL);
-
- DBG2(" not before : %T", &this->notBefore);
- DBG2(" current time: %T", &current_time);
- DBG2(" not after : %T", &this->notAfter);
-
- if (until != NULL &&
- (*until == UNDEFINED_TIME || this->notAfter < *until))
- {
- *until = this->notAfter;
- }
- if (current_time < this->notBefore)
- {
- return "is not valid yet";
- }
- if (current_time > this->notAfter)
- {
- return "has expired";
- }
- DBG2(" attribute certificate is valid");
- return NULL;
-}
-
-/**
- * Implements x509ac_t.is_newer
- */
-static bool is_newer(const private_x509ac_t *this, const private_x509ac_t *other)
-{
- return this->notBefore > other->notBefore;
-}
-
-/**
- * Implements x509ac_t.equals_holder.
- */
-static bool equals_holder(const private_x509ac_t *this, const private_x509ac_t *other)
-{
- return this->holderIssuer->equals(this->holderIssuer, other->holderIssuer)
- && chunk_equals(this->holderSerial, other->holderSerial);
-}
-
-/**
- * parses a directoryName
- */
-static bool parse_directoryName(chunk_t blob, int level, bool implicit, identification_t **name)
-{
- bool has_directoryName;
- linked_list_t *list = linked_list_create();
-
- x509_parse_generalNames(blob, level, implicit, list);
- has_directoryName = list->get_count(list) > 0;
-
- if (has_directoryName)
- {
- iterator_t *iterator = list->create_iterator(list, TRUE);
- identification_t *directoryName;
- bool first = TRUE;
-
- while (iterator->iterate(iterator, (void**)&directoryName))
- {
- if (first)
- {
- *name = directoryName;
- first = FALSE;
- }
- else
- {
- DBG1("more than one directory name - first selected");
- directoryName->destroy(directoryName);
- }
- }
- iterator->destroy(iterator);
- }
- else
- {
- DBG1("no directoryName found");
- }
-
- list->destroy(list);
- return has_directoryName;
-}
-
-/**
- * parses roleSyntax
- */
-static void parse_roleSyntax(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
- while (objectID < ROLE_ROOF)
- {
- if (!extract_object(roleSyntaxObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
-
- switch (objectID)
- {
- default:
- break;
- }
- objectID++;
- }
-}
-
-/**
- * Parses an X.509 attribute certificate
- */
-static bool parse_certificate(chunk_t blob, private_x509ac_t *this)
-{
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int type = OID_UNKNOWN;
- int extn_oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, 0, FALSE, FALSE);
- while (objectID < AC_OBJ_ROOF)
- {
- if (!extract_object(acObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- /* those objects which will parsed further need the next higher level */
- level++;
-
- switch (objectID)
- {
- case AC_OBJ_CERTIFICATE:
- this->certificate = object;
- break;
- case AC_OBJ_CERTIFICATE_INFO:
- this->certificateInfo = object;
- break;
- case AC_OBJ_VERSION:
- this->version = (object.len) ? (1 + (u_int)*object.ptr) : 1;
- DBG2(" v%d", this->version);
- if (this->version != 2)
- {
- DBG1("v%d attribute certificates are not supported", this->version);
- return FALSE;
- }
- break;
- case AC_OBJ_HOLDER_ISSUER:
- if (!parse_directoryName(object, level, FALSE, &this->holderIssuer))
- {
- return FALSE;
- }
- break;
- case AC_OBJ_HOLDER_SERIAL:
- this->holderSerial = object;
- break;
- case AC_OBJ_ENTITY_NAME:
- if (!parse_directoryName(object, level, TRUE, &this->entityName))
- {
- return FALSE;
- }
- break;
- case AC_OBJ_ISSUER_NAME:
- if (!parse_directoryName(object, level, FALSE, &this->issuerName))
- {
- return FALSE;
- }
- break;
- case AC_OBJ_SIG_ALG:
- this->sigAlg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case AC_OBJ_SERIAL_NUMBER:
- this->serialNumber = object;
- break;
- case AC_OBJ_NOT_BEFORE:
- this->notBefore = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case AC_OBJ_NOT_AFTER:
- this->notAfter = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case AC_OBJ_ATTRIBUTE_TYPE:
- type = known_oid(object);
- break;
- case AC_OBJ_ATTRIBUTE_VALUE:
- {
- switch (type)
- {
- case OID_AUTHENTICATION_INFO:
- DBG2(" need to parse authenticationInfo");
- break;
- case OID_ACCESS_IDENTITY:
- DBG2(" need to parse accessIdentity");
- break;
- case OID_CHARGING_IDENTITY:
- ietfAttr_list_create_from_chunk(object, this->charging, level);
- break;
- case OID_GROUP:
- ietfAttr_list_create_from_chunk(object, this->groups, level);
- break;
- case OID_ROLE:
- parse_roleSyntax(object, level);
- break;
- default:
- break;
- }
- }
- break;
- case AC_OBJ_EXTN_ID:
- extn_oid = known_oid(object);
- break;
- case AC_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG2(" %s",(critical)?"TRUE":"FALSE");
- break;
- case AC_OBJ_EXTN_VALUE:
- {
- switch (extn_oid)
- {
- case OID_CRL_DISTRIBUTION_POINTS:
- DBG2(" need to parse crlDistributionPoints");
- break;
- case OID_AUTHORITY_KEY_ID:
- x509_parse_authorityKeyIdentifier(object, level,
- &this->authKeyID, &this->authKeySerialNumber);
- break;
- case OID_TARGET_INFORMATION:
- DBG2(" need to parse targetInformation");
- break;
- case OID_NO_REV_AVAIL:
- this->noRevAvail = TRUE;
- break;
- default:
- break;
- }
- }
- break;
- case AC_OBJ_ALGORITHM:
- this->algorithm = parse_algorithmIdentifier(object, level, NULL);
- break;
- case AC_OBJ_SIGNATURE:
- this->signature = object;
- break;
- default:
- break;
- }
- objectID++;
- }
- this->installed = time(NULL);
- return TRUE;
-}
-
-/**
- * Implementation of x509ac_t.list.
- */
-static void list(const private_x509ac_t *this, FILE *out, bool utc)
-{
- time_t now = time(NULL);
-
- fprintf(out, "%#T\n", &this->installed, utc);
-
- if (this->entityName)
- {
- fprintf(out, " holder: '%D'\n", this->entityName);
- }
- if (this->holderIssuer)
- {
- fprintf(out, " hissuer: '%D'\n", this->holderIssuer);
- }
- if (this->holderSerial.ptr)
- {
- fprintf(out, " hserial: %#B\n", &this->holderSerial);
- }
-
- /* list all group attributes on a single line */
- fprintf(out, " groups: ");
- ietfAttr_list_list(this->groups, out);
- fprintf(out, "\n");
-
- fprintf(out, " issuer: '%D'\n", this->issuerName);
- fprintf(out, " serial: %#B\n", &this->serialNumber);
-
- fprintf(out, " validity: not before %#T, ", &this->notBefore, utc);
- if (now < this->notBefore)
- {
- fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore);
- }
- else
- {
- fprintf(out, "ok\n");
- }
-
- fprintf(out, " not after %#T, ", &this->notAfter, utc);
- if (now > this->notAfter)
- {
- fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter);
- }
- else
- {
- fprintf(out, "ok");
- if (now > this->notAfter - ACERT_WARNING_INTERVAL * 60 * 60 * 24)
- {
- fprintf(out, " (expires in %#V)", &now, &this->notAfter);
- }
- fprintf(out, " \n");
- }
-
- if (this->authKeyID.ptr)
- {
- fprintf(out, " authkey: %#B\n", &this->authKeyID);
- }
- if (this->authKeySerialNumber.ptr)
- {
- fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber);
- }
-}
-
-/**
- * Implements x509ac_t.destroy
- */
-static void destroy(private_x509ac_t *this)
-{
- DESTROY_IF(this->holderIssuer);
- DESTROY_IF(this->entityName);
- DESTROY_IF(this->issuerName);
- ietfAttr_list_destroy(this->charging);
- ietfAttr_list_destroy(this->groups);
- free(this->certificate.ptr);
- free(this);
-}
-
-/**
- * Described in header.
- */
-x509ac_t *x509ac_create_from_chunk(chunk_t chunk)
-{
- private_x509ac_t *this = malloc_thing(private_x509ac_t);
-
- /* initialize */
- this->holderIssuer = NULL;
- this->entityName = NULL;
- this->issuerName = NULL;
- this->charging = linked_list_create();
- this->groups = linked_list_create();
-
- /* public functions */
- this->public.is_valid = (err_t (*) (const x509ac_t*,time_t*))is_valid;
- this->public.is_newer = (bool (*) (const x509ac_t*,const x509ac_t*))is_newer;
- this->public.equals_holder = (bool (*) (const x509ac_t*,const x509ac_t*))equals_holder;
- this->public.list = (void (*) (const x509ac_t*,FILE*,bool))list;
- this->public.destroy = (void (*) (x509ac_t*))destroy;
-
- if (!parse_certificate(chunk, this))
- {
- destroy(this);
- return NULL;
- }
- return &this->public;
-}
-
-/**
- * Described in header.
- */
-x509ac_t *x509ac_create_from_file(const char *filename)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
-
- if (!pem_asn1_load_file(filename, NULL, "attribute certificate", &chunk, &pgp))
- {
- return NULL;
- }
- return x509ac_create_from_chunk(chunk);
-}
-
diff --git a/src/libstrongswan/crypto/ac.h b/src/libstrongswan/crypto/ac.h
deleted file mode 100644
index 8a4ccbd4c..000000000
--- a/src/libstrongswan/crypto/ac.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/**
- * @file ac.h
- *
- * @brief Interface of x509ac_t.
- *
- */
-
-/*
- * Copyright (C) 2002 Ueli Galizzi, Ariane Seiler
- * Copyright (C) 2003 Martin Berner, Lukas Suter
- * Copyright (C) 2007 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: ac.h 3300 2007-10-12 21:53:18Z andreas $
- */
-
-#ifndef AC_H_
-#define AC_H_
-
-#include <library.h>
-
-typedef struct x509ac_t x509ac_t;
-
-/**
- * @brief X.509 attribute certificate.
- *
- * @b Constructors:
- * - x509ac_create_from_chunk()
- * - x509ac_create_from_file()
- *
- * @ingroup crypto
- */
-struct x509ac_t {
-
- /**
- * @brief Checks the validity interval of the attribute certificate
- *
- * @param this certificate being examined
- * @param until until = min(until, notAfter)
- * @return NULL if the certificate is valid
- */
- err_t (*is_valid) (const x509ac_t *this, time_t *until);
-
- /** @brief Checks if this attr cert is newer than the other attr cert
- *
- * @param this calling object
- * @param other other attr cert object
- * @return TRUE if this was issued more recently than other
- */
- bool (*is_newer) (const x509ac_t *this, const x509ac_t *other);
-
- /**
- * @brief Checks if two attribute certificates belong to the same holder
- *
- * @param this calling attribute certificate
- * @param that other attribute certificate
- * @return TRUE if same holder
- */
- bool (*equals_holder) (const x509ac_t *this, const x509ac_t *other);
-
- /**
- * @brief Log the attribute certificate info to out.
- *
- * @param this calling object
- * @param out stream to write to
- * @param utc TRUE for UTC times, FALSE for local time
- */
- void (*list)(const x509ac_t *this, FILE *out, bool utc);
-
- /**
- * @brief Destroys the attribute certificate.
- *
- * @param this certificate to destroy
- */
- void (*destroy) (x509ac_t *this);
-};
-
-/**
- * @brief Read a x509 attribute certificate from a DER encoded blob.
- *
- * @param chunk chunk containing DER encoded data
- * @return created x509ac_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509ac_t *x509ac_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Read a x509 attribute certificate from a DER encoded file.
- *
- * @param filename file containing DER encoded data
- * @return created x509ac_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509ac_t *x509ac_create_from_file(const char *filename);
-
-#endif /* AC_H_ */
-
diff --git a/src/libstrongswan/crypto/ca.c b/src/libstrongswan/crypto/ca.c
deleted file mode 100644
index 510e3528e..000000000
--- a/src/libstrongswan/crypto/ca.c
+++ /dev/null
@@ -1,813 +0,0 @@
-/**
- * @file ca.c
- *
- * @brief Implementation of ca_info_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <pthread.h>
-
-#include "x509.h"
-#include "crl.h"
-#include "ca.h"
-#include "ac.h"
-#include "certinfo.h"
-#include "ocsp.h"
-
-#include <library.h>
-#include <debug.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-#include <utils/fetcher.h>
-
-typedef struct private_ca_info_t private_ca_info_t;
-
-/**
- * Private data of a ca_info_t object.
- */
-struct private_ca_info_t {
- /**
- * Public interface for this ca info record
- */
- ca_info_t public;
-
- /**
- * Name of the ca info record
- */
- char *name;
-
- /**
- * Time when ca info record was installed
- */
- time_t installed;
-
- /**
- * Distinguished Name of the CA
- */
- x509_t *cacert;
-
- /**
- * List of attribute certificates
- */
- linked_list_t *attrcerts;
-
- /**
- * List of crl URIs
- */
- linked_list_t *crluris;
-
- /**
- * List of ocsp URIs
- */
- linked_list_t *ocspuris;
-
- /**
- * CRL issued by this ca
- */
- crl_t *crl;
-
- /**
- * List of certificate info records
- */
- linked_list_t *certinfos;
-
- /**
- * mutex controls access to the elements:
- * name, crluris, ocspuris, crl, and certinfos
- */
- pthread_mutex_t mutex;
-};
-
-/**
- * static options set by ca_info_set_options()
- */
-static strict_t strict_crl_policy = STRICT_NO;
-static bool cache_crls = FALSE;
-static u_int crl_check_interval = 0;
-
-/**
- * Implements ca_info_t.equals
- */
-static bool equals(const private_ca_info_t *this, const private_ca_info_t *that)
-{
- return chunk_equals(this->cacert->get_keyid(this->cacert),
- that->cacert->get_keyid(that->cacert));
-}
-
-/**
- * Implements ca_info_t.equals_name_release_info
- */
-static bool equals_name_release_info(private_ca_info_t *this, const char *name)
-{
- bool found;
-
- pthread_mutex_lock(&(this->mutex));
- found = this->name != NULL && streq(this->name, name);
-
- if (found)
- {
- this->crluris->destroy_offset(this->crluris,
- offsetof(identification_t, destroy));
- this->crluris = linked_list_create();
-
- this->ocspuris->destroy_offset(this->ocspuris,
- offsetof(identification_t, destroy));
- this->ocspuris = linked_list_create();
-
- free(this->name);
- this->name = NULL;
- }
-
- pthread_mutex_unlock(&(this->mutex));
- return found;
-}
-
-/**
- * Implements ca_info_t.is_crl_issuer
- */
-static bool is_cert_issuer(private_ca_info_t *this, const x509_t *cert)
-{
- return cert->is_issuer(cert, this->cacert);
-}
-
-/**
- * Implements ca_info_t.is_crl_issuer
- */
-static bool is_crl_issuer(private_ca_info_t *this, const crl_t *crl)
-{
- return crl->is_issuer(crl, this->cacert);
-}
-
-/**
- * Implements ca_info_t.is_ca
- */
-static bool is_ca(private_ca_info_t *this)
-{
- return this->cacert->is_ca(this->cacert);
-}
-
-/**
- * Implements ca_info_t.is_strict
- */
-static bool is_strict(private_ca_info_t *this)
-{
- bool strict = strict_crl_policy != STRICT_NO;
-
- if (strict_crl_policy == STRICT_IFURI)
- {
- pthread_mutex_lock(&(this->mutex));
- strict = this->crluris->get_count(this->crluris) > 0 ||
- this->ocspuris->get_count(this->ocspuris) > 0;
- pthread_mutex_unlock(&(this->mutex));
- }
- return strict;
-}
-
-/**
- * Implements ca_info_t.has_crl
- */
-static bool has_crl(private_ca_info_t *this)
-{
- bool found;
-
- pthread_mutex_lock(&(this->mutex));
- found = this->crl != NULL;
- pthread_mutex_unlock(&(this->mutex));
-
- return found;
-}
-
-/**
- * Implements ca_info_t.has_certinfos
- */
-static bool has_certinfos(private_ca_info_t *this)
-{
- bool found;
-
- pthread_mutex_lock(&(this->mutex));
- found = this->certinfos->get_count(this->certinfos) > 0;
- pthread_mutex_unlock(&(this->mutex));
-
- return found;
-}
-
-/**
- * Implements ca_info_t.add_crl
- */
-static void add_crl(private_ca_info_t *this, crl_t *crl)
-{
- pthread_mutex_lock(&(this->mutex));
-
- if (this->crl)
- {
- if (crl->is_newer(crl, this->crl))
- {
- this->crl->destroy(this->crl);
- this->crl = crl;
- DBG1(" this crl is newer - existing crl replaced");
- }
- else
- {
- crl->destroy(crl);
- DBG1(" this crl is not newer - existing crl retained");
- }
- }
- else
- {
- this->crl = crl;
- DBG2(" crl added");
- }
-
- pthread_mutex_unlock(&(this->mutex));
-}
-
-/**
- * Implements ca_info_t.list_crl
- */
-static void list_crl(private_ca_info_t *this, FILE *out, bool utc)
-{
- pthread_mutex_lock(&this->mutex);
- this->crl->list(this->crl, out, utc);
- pthread_mutex_unlock(&this->mutex);
-}
-
-/**
- * Implements ca_info_t.list_certinfos
- */
-static void list_certinfos(private_ca_info_t *this, FILE *out, bool utc)
-{
- iterator_t *iterator;
- certinfo_t *certinfo;
- chunk_t authkey;
-
- pthread_mutex_lock(&this->mutex);
-
- authkey = this->cacert->get_subjectKeyID(this->cacert);
- fprintf(out," authname: '%D'\n", this->cacert->get_subject(this->cacert));
- fprintf(out," authkey: %#B\n", &authkey);
-
- iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
- while (iterator->iterate(iterator, (void**)&certinfo))
- {
- time_t nextUpdate, thisUpdate, now;
- chunk_t serial;
-
- now = time(NULL);
- nextUpdate = certinfo->get_nextUpdate(certinfo);
- thisUpdate = certinfo->get_thisUpdate(certinfo);
- serial = certinfo->get_serialNumber(certinfo);
-
- fprintf(out, "%#T, until %#T, ", &thisUpdate, utc, &nextUpdate, utc);
- if (now > nextUpdate)
- {
- fprintf(out, "expired (%#V ago)\n", &now, &nextUpdate);
- }
- else
- {
- fprintf(out, "ok (expires in %#V)\n", &now, &nextUpdate);
- }
- fprintf(out, " serial: %#B, %N\n", &serial,
- cert_status_names, certinfo->get_status(certinfo));
- }
- iterator->destroy(iterator);
-
- pthread_mutex_unlock(&this->mutex);
-}
-
-/**
- * Find an exact copy of an identification in a linked list
- */
-static identification_t* find_identification(linked_list_t *list, identification_t *id)
-{
- identification_t *found_id = NULL, *current_id;
-
- iterator_t *iterator = list->create_iterator(list, TRUE);
-
- while (iterator->iterate(iterator, (void**)&current_id))
- {
- if (id->equals(id, current_id))
- {
- found_id = current_id;
- break;
- }
- }
- iterator->destroy(iterator);
-
- return found_id;
-}
-
-/**
- * Add a unique identification to a linked list
- */
-static identification_t *add_identification(linked_list_t *list, identification_t *id)
-{
- identification_t *found_id = find_identification(list, id);
-
- if (found_id)
- {
- id->destroy(id);
- return found_id;
- }
- else
- {
- list->insert_last(list, (void*)id);
- return id;
- }
-}
-
-/**
- * Implements ca_info_t.add_crluri
- */
-static void add_crluri(private_ca_info_t *this, chunk_t uri)
-{
- if (uri.len < 6 ||
- (strncasecmp(uri.ptr, "http", 4) != 0 &&
- strncasecmp(uri.ptr, "ldap", 4) != 0 &&
- strncasecmp(uri.ptr, "file", 4) != 0 &&
- strncasecmp(uri.ptr, "ftp", 3) != 0))
- {
- DBG1(" invalid crl uri '%.*s'", uri.len, uri.ptr);
- return;
- }
- else
- {
- identification_t *crluri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
-
- pthread_mutex_lock(&(this->mutex));
- add_identification(this->crluris, crluri);
- pthread_mutex_unlock(&(this->mutex));
- }
-}
-
-/**
- * Implements ca_info_t.add_ocspuri
- */
-static void add_ocspuri(private_ca_info_t *this, chunk_t uri)
-{
- if (uri.len < 7 || strncasecmp(uri.ptr, "http", 4) != 0)
- {
- DBG1(" invalid ocsp uri '%.*s'", uri.len, uri.ptr);
- return;
- }
- else
- {
- identification_t *ocspuri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
-
- pthread_mutex_lock(&(this->mutex));
- add_identification(this->ocspuris, ocspuri);
- pthread_mutex_unlock(&(this->mutex));
- }
-}
-
-/**
- * Implements ca_info_t.add_info.
- */
-void add_info (private_ca_info_t *this, const private_ca_info_t *that)
-{
- pthread_mutex_lock(&(this->mutex));
-
- if (this->name == NULL && that->name != NULL)
- {
- this->name = strdup(that->name);
- }
-
- pthread_mutex_unlock(&(this->mutex));
-
- {
- identification_t *uri;
-
- iterator_t *iterator = that->crluris->create_iterator(that->crluris, TRUE);
-
- while (iterator->iterate(iterator, (void**)&uri))
- {
- if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
- {
- add_crluri(this, uri->get_encoding(uri));
- }
- }
- iterator->destroy(iterator);
- }
-
- {
- identification_t *uri;
-
- iterator_t *iterator = that->ocspuris->create_iterator(that->ocspuris, TRUE);
-
- while (iterator->iterate(iterator, (void**)&uri))
- {
- if (uri->get_type(uri) == ID_DER_ASN1_GN_URI)
- {
- add_ocspuri(this, uri->get_encoding(uri));
- }
- }
- iterator->destroy(iterator);
- }
-}
-
-/**
- * Implements ca_info_t.get_certificate.
- */
-static x509_t* get_certificate(private_ca_info_t* this)
-{
- return this->cacert;
-}
-
-/**
- * caches a crl by saving it to a given crl directory
- */
-void cache_crl(private_ca_info_t* this, const char *crl_dir, crl_t *crl)
-{
- char buffer[BUF_LEN];
- char *path;
- char *pos = buffer;
- int len = BUF_LEN;
- int n;
-
- chunk_t authKeyID = this->cacert->get_subjectKeyID(this->cacert);
- chunk_t uri;
-
- uri.ptr = buffer;
- uri.len = 7 + strlen(crl_dir) + 1 + 2*authKeyID.len + 4;
-
- if (uri.len >= BUF_LEN)
- {
- DBG1("file uri exceeds buffer length of %d bytes - crl not saved", BUF_LEN);
- return;
- }
-
- /* print the file uri prefix */
- n = snprintf(pos, len, "file://");
- pos += n; len -= n;
-
- /* remember the start of the path string */
- path = pos;
-
- /* print the default crl directory path */
- n = snprintf(pos, len, "%s/", crl_dir);
- pos += n; len -= n;
-
- /* create and print a unique crl filename derived from the authKeyID */
- while (authKeyID.len-- > 0)
- {
- n = snprintf(pos, len, "%02x", *authKeyID.ptr++);
- pos += n; len -= n;
- }
-
- /* add the file suffix */
- n = snprintf(pos, len, ".crl");
-
- if (crl->write_to_file(crl, path, 0022, TRUE))
- {
- identification_t *crluri = identification_create_from_encoding(ID_DER_ASN1_GN_URI, uri);
-
- add_identification(this->crluris, crluri);
- }
-}
-
-/**
- * Implements ca_info_t.verify_by_crl.
- */
-static cert_status_t verify_by_crl(private_ca_info_t* this, certinfo_t *certinfo,
- const char *crl_dir)
-{
- rsa_public_key_t *issuer_public_key = this->cacert->get_public_key(this->cacert);
- bool stale;
-
- pthread_mutex_lock(&(this->mutex));
- if (this->crl == NULL)
- {
- stale = TRUE;
- DBG1("no crl is locally available");
- }
- else
- {
- stale = !this->crl->is_valid(this->crl);
- DBG1("crl is %s", stale? "stale":"valid");
- }
-
- if (stale && crl_check_interval > 0)
- {
- iterator_t *iterator = this->crluris->create_iterator(this->crluris, TRUE);
- identification_t *uri;
-
- while (iterator->iterate(iterator, (void**)&uri))
- {
- fetcher_t *fetcher;
- char uri_string[BUF_LEN];
- chunk_t uri_chunk = uri->get_encoding(uri);
- chunk_t response_chunk;
-
- snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr);
- fetcher = fetcher_create(uri_string);
-
- response_chunk = fetcher->get(fetcher);
- fetcher->destroy(fetcher);
- if (response_chunk.ptr != NULL)
- {
- crl_t *crl = crl_create_from_chunk(response_chunk);
-
- if (crl == NULL)
- {
- free(response_chunk.ptr);
- continue;
- }
- if (!is_crl_issuer(this, crl))
- {
- DBG1(" fetched crl has wrong issuer");
- crl->destroy(crl);
- continue;
- }
- if (!crl->verify(crl, issuer_public_key))
- {
- DBG1("fetched crl signature is invalid");
- crl->destroy(crl);
- continue;
- }
- DBG2("fetched crl signature is valid");
-
- if (this->crl == NULL)
- {
- this->crl = crl;
- }
- else if (crl->is_newer(crl, this->crl))
- {
- this->crl->destroy(this->crl);
- this->crl = crl;
- DBG1("this crl is newer - existing crl replaced");
- }
- else
- {
- crl->destroy(crl);
- DBG1("this crl is not newer - existing crl retained");
- continue;
- }
- if (crl->is_valid(crl))
- {
- if (cache_crls && strncasecmp(uri_string, "file", 4) != 0)
- {
- cache_crl(this, crl_dir, crl);
- }
- /* we found a valid crl and therefore exit the fetch loop */
- break;
- }
- else
- {
- DBG1("fetched crl is stale");
- }
- }
- }
- iterator->destroy(iterator);
- }
-
- if (this->crl)
- {
- if (!this->crl->verify(this->crl, issuer_public_key))
- {
- DBG1("crl signature is invalid");
- goto ret;
- }
- DBG2("crl signature is valid");
-
- this->crl->get_status(this->crl, certinfo);
- }
-
-ret:
- pthread_mutex_unlock(&(this->mutex));
- return certinfo->get_status(certinfo);
-}
-
-/**
- * Implements ca_info_t.verify_by_ocsp.
- */
-static cert_status_t verify_by_ocsp(private_ca_info_t* this,
- certinfo_t *certinfo,
- credential_store_t *credentials)
-{
- bool stale;
- iterator_t *iterator;
- certinfo_t *cached_certinfo = NULL;
- int comparison = 1;
-
- pthread_mutex_lock(&(this->mutex));
-
- /* do we support OCSP at all? */
- if (this->ocspuris->get_count(this->ocspuris) == 0)
- {
- goto ret;
- }
-
- iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
-
- /* find the list insertion point in alphabetical order */
- while(iterator->iterate(iterator, (void**)&cached_certinfo))
- {
- comparison = certinfo->compare_serialNumber(certinfo, cached_certinfo);
-
- if (comparison <= 0)
- {
- break;
- }
- }
-
- /* do we have a valid certinfo_t for this serial number in our cache? */
- if (comparison == 0)
- {
- stale = cached_certinfo->get_nextUpdate(cached_certinfo) < time(NULL);
- DBG1("ocsp status in cache is %s", stale ? "stale":"fresh");
- }
- else
- {
- stale = TRUE;
- DBG1("ocsp status is not in cache");
- }
-
- if (stale)
- {
- ocsp_t *ocsp;
-
- ocsp = ocsp_create(this->cacert, this->ocspuris);
- ocsp->fetch(ocsp, certinfo, credentials);
- if (certinfo->get_status(certinfo) != CERT_UNDEFINED)
- {
- if (comparison != 0)
- {
- cached_certinfo = certinfo_create(certinfo->get_serialNumber(certinfo));
-
- if (comparison > 0)
- {
- this->certinfos->insert_last(this->certinfos, (void *)cached_certinfo);
- }
- else
- {
- iterator->insert_before(iterator, (void *)cached_certinfo);
- }
- }
- cached_certinfo->update(cached_certinfo, certinfo);
- }
- ocsp->destroy(ocsp);
- }
- else
- {
- certinfo->update(certinfo, cached_certinfo);
- }
-
- iterator->destroy(iterator);
-
-ret:
- pthread_mutex_unlock(&(this->mutex));
- return certinfo->get_status(certinfo);
-}
-
-/**
- * Implements ca_info_t.purge_ocsp
- */
-static void purge_ocsp(private_ca_info_t *this)
-{
- pthread_mutex_lock(&(this->mutex));
-
- this->certinfos->destroy_offset(this->certinfos,
- offsetof(certinfo_t, destroy));
- this->certinfos = linked_list_create();
-
- pthread_mutex_unlock(&(this->mutex));
-}
-
-/**
- * Implements ca_info_t.destroy
- */
-static void destroy(private_ca_info_t *this)
-{
- this->attrcerts->destroy_offset(this->attrcerts,
- offsetof(x509ac_t, destroy));
- this->crluris->destroy_offset(this->crluris,
- offsetof(identification_t, destroy));
- this->ocspuris->destroy_offset(this->ocspuris,
- offsetof(identification_t, destroy));
- this->certinfos->destroy_offset(this->certinfos,
- offsetof(certinfo_t, destroy));
- DESTROY_IF(this->crl);
- free(this->name);
- free(this);
-}
-
-/**
- * list the info of this CA
- */
-static void list(private_ca_info_t* this, FILE* out, bool utc)
-{
- chunk_t chunk;
- identification_t *uri;
- iterator_t *iterator;
- bool first;
-
- pthread_mutex_lock(&(this->mutex));
- fprintf(out, "%#T", &this->installed, utc);
-
- if (this->name)
- {
- fprintf(out, ", \"%s\"\n", this->name);
- }
- else
- {
- fprintf(out, "\n");
- }
-
- fprintf(out, " authname: '%D'\n", this->cacert->get_subject(this->cacert));
- chunk = this->cacert->get_subjectKeyID(this->cacert);
- fprintf(out, " authkey: %#B\n", &chunk);
- chunk = this->cacert->get_keyid(this->cacert);
- fprintf(out, " keyid: %#B\n", &chunk);
-
- first = TRUE;
- iterator = this->crluris->create_iterator(this->crluris, TRUE);
- while (iterator->iterate(iterator, (void**)&uri))
- {
- fprintf(out, " %s '%D'\n", first ? "crluris:":" ", uri);
- first = FALSE;
- }
- iterator->destroy(iterator);
-
- first = TRUE;
- iterator = this->ocspuris->create_iterator(this->ocspuris, TRUE);
- while (iterator->iterate(iterator, (void**)&uri))
- {
- fprintf(out, " %s '%D'\n", first ? "ocspuris:":" ", uri);
- first = FALSE;
- }
- iterator->destroy(iterator);
- pthread_mutex_unlock(&(this->mutex));
-}
-
-/*
- * Described in header.
- */
-void ca_info_set_options(strict_t strict, bool cache, u_int interval)
-{
- strict_crl_policy = strict;
- cache_crls = cache;
- crl_check_interval = interval;
-}
-
-/*
- * Described in header.
- */
-ca_info_t *ca_info_create(const char *name, x509_t *cacert)
-{
- private_ca_info_t *this = malloc_thing(private_ca_info_t);
-
- /* initialize */
- this->installed = time(NULL);
- this->name = (name == NULL)? NULL:strdup(name);
- this->cacert = cacert;
- this->attrcerts = linked_list_create();
- this->crluris = linked_list_create();
- this->ocspuris = linked_list_create();
- this->certinfos = linked_list_create();
- this->crl = NULL;
-
- /* initialize the mutex */
- pthread_mutex_init(&(this->mutex), NULL);
-
- /* public functions */
- this->public.equals = (bool (*) (const ca_info_t*,const ca_info_t*))equals;
- this->public.equals_name_release_info = (bool (*) (ca_info_t*,const char*))equals_name_release_info;
- this->public.is_cert_issuer = (bool (*) (ca_info_t*,const x509_t*))is_cert_issuer;
- this->public.is_crl_issuer = (bool (*) (ca_info_t*,const crl_t*))is_crl_issuer;
- this->public.is_ca = (bool (*) (ca_info_t*))is_ca;
- this->public.is_strict = (bool (*) (ca_info_t*))is_strict;
- this->public.add_info = (void (*) (ca_info_t*,const ca_info_t*))add_info;
- this->public.add_crl = (void (*) (ca_info_t*,crl_t*))add_crl;
- this->public.has_crl = (bool (*) (ca_info_t*))has_crl;
- this->public.has_certinfos = (bool (*) (ca_info_t*))has_certinfos;
- this->public.list = (void (*) (ca_info_t*,FILE*,bool))list;
- this->public.list_crl = (void (*) (ca_info_t*,FILE*,bool))list_crl;
- this->public.list_certinfos = (void (*) (ca_info_t*,FILE*,bool))list_certinfos;
- this->public.add_crluri = (void (*) (ca_info_t*,chunk_t))add_crluri;
- this->public.add_ocspuri = (void (*) (ca_info_t*,chunk_t))add_ocspuri;
- this->public.get_certificate = (x509_t* (*) (ca_info_t*))get_certificate;
- this->public.verify_by_crl = (cert_status_t (*) (ca_info_t*,certinfo_t*, const char*))verify_by_crl;
- this->public.verify_by_ocsp = (cert_status_t (*) (ca_info_t*,certinfo_t*,credential_store_t*))verify_by_ocsp;
- this->public.purge_ocsp = (void (*) (ca_info_t*))purge_ocsp;
- this->public.destroy = (void (*) (ca_info_t*))destroy;
-
- return &this->public;
-}
diff --git a/src/libstrongswan/crypto/ca.h b/src/libstrongswan/crypto/ca.h
deleted file mode 100644
index ff6271b15..000000000
--- a/src/libstrongswan/crypto/ca.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/**
- * @file ca.h
- *
- * @brief Interface of ca_info_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef CA_H_
-#define CA_H_
-
-typedef struct ca_info_t ca_info_t;
-
-#include <library.h>
-
-#include "x509.h"
-#include "crl.h"
-
-#define MAX_CA_PATH_LEN 7
-
-/*forward declaration */
-struct credential_store_t;
-
-/**
- * @brief X.509 certification authority information record
- *
- * @b Constructors:
- * - ca_info_create()
- *
- * @ingroup transforms
- */
-struct ca_info_t {
-
- /**
- * @brief Compare two ca info records
- *
- * Comparison is done via the keyid of the ca certificate
- *
- * @param this first ca info object
- * @param that second ca info objct
- * @return TRUE if a match is found
- */
- bool (*equals) (const ca_info_t *this, const ca_info_t* that);
-
- /**
- * @brief If the ca info record has the same name then release the name and URIs
- *
- * @param this ca info object
- * @return TRUE if a match is found
- */
- bool (*equals_name_release_info) (ca_info_t *this, const char *name);
-
- /**
- * @brief Checks if a certificate was issued by this ca
- *
- * @param this ca info object
- * @param cert certificate to be checked
- * @return TRUE if the issuing ca has been found
- */
- bool (*is_cert_issuer) (ca_info_t *this, const x509_t *cert);
-
- /**
- * @brief Checks if a crl was issued by this ca
- *
- * @param this ca info object
- * @param crl crl to be checked
- * @return TRUE if the issuing ca has been found
- */
- bool (*is_crl_issuer) (ca_info_t *this, const crl_t *crl);
-
- /**
- * @brief Checks if the ca certificate has the isCA flag set
- *
- * @param this ca info object
- * @return TRUE if the isCA flag is set
- */
- bool (*is_ca) (ca_info_t *this);
-
- /**
- * @brief Checks if the ca enforces a strict crl policy
- *
- * @param this ca info object
- * @return TRUE if the crl policy is strict
- */
- bool (*is_strict) (ca_info_t *this);
-
- /**
- * @brief Merges info from a secondary ca info object
- *
- * @param this primary ca info object
- * @param that secondary ca info object
- */
- void (*add_info) (ca_info_t *this, const ca_info_t *that);
-
- /**
- * @brief Adds a new or replaces an obsoleted CRL
- *
- * @param this ca info object
- * @param crl crl to be added
- */
- void (*add_crl) (ca_info_t *this, crl_t *crl);
-
- /**
- * @brief Does the CA have a CRL?
- *
- * @param this ca info object
- * @return TRUE if crl is available
- */
- bool (*has_crl) (ca_info_t *this);
-
- /**
- * @brief Does the CA have OCSP certinfos?
- *
- * @param this ca info object
- * @return TRUE if there are any certinfos
- */
- bool (*has_certinfos) (ca_info_t *this);
-
- /**
- * @brief Print the CA info onto the console
- *
- * @param this ca info object
- * @param out output stream
- * @param utc TRUE - utc
- FALSE - local time
- */
- void (*list) (ca_info_t *this, FILE *out, bool utc);
-
- /**
- * @brief List the CRL onto the console
- *
- * @param this ca info object
- * @param out output stream
- * @param utc TRUE - utc
- FALSE - local time
- */
- void (*list_crl) (ca_info_t *this, FILE *out, bool utc);
-
- /**
- * @brief List the OCSP certinfos onto the console
- *
- * @param this ca info object
- * @param out output stream
- * @param utc TRUE - utc
- FALSE - local time
- */
- void (*list_certinfos) (ca_info_t *this, FILE *out, bool utc);
-
- /**
- * @brief Adds a CRL URI to a list
- *
- * @param this ca info object
- * @param uri crl uri to be added
- */
- void (*add_crluri) (ca_info_t *this, chunk_t uri);
-
- /**
- * @brief Adds a OCSP URI to a list
- *
- * @param this ca info object
- * @param uri ocsp uri to be added
- */
- void (*add_ocspuri) (ca_info_t *this, chunk_t uri);
-
- /**
- * @brief Get the ca certificate
- *
- * @param this ca info object
- * @return ca certificate
- */
- x509_t* (*get_certificate) (ca_info_t *this);
-
- /**
- * @brief Verify the status of a certificate by CRL
- *
- * @param this ca info object
- * @param certinfo detailed certificate status information
- * @param crl_dir directory where fetched crls should be stored
- * @return certificate status
- */
- cert_status_t (*verify_by_crl) (ca_info_t *this, certinfo_t *certinfo, const char *crl_dir);
-
- /**
- * @brief Verify the status of a certificate by OCSP
- *
- * @param this ca info object
- * @param certinfo detailed certificate status information
- * @param credentials credential store needed for trust path verification
- * @return certificate status
- */
- cert_status_t (*verify_by_ocsp) (ca_info_t* this, certinfo_t* certinfo, struct credential_store_t* credentials);
-
- /**
- * @brief Purge the OCSP certinfos of a ca info record
- *
- * @param this ca info object
- */
- void (*purge_ocsp) (ca_info_t *this);
-
- /**
- * @brief Destroys a ca info record
- *
- * @param this ca info to destroy
- */
- void (*destroy) (ca_info_t *this);
-};
-
-/**
- * @brief Set ca info options
- *
- * @param cache TRUE if crls shall be cached by storing them
- * @param interval crl_check_interval to be set in seconds
- *
- * @ingroup crypto
- */
-void ca_info_set_options(strict_t strict, bool cache, u_int interval);
-
-/**
- * @brief Create a ca info record
- *
- * @param name name of the ca info record
- * @param cacert path to the ca certificate
- * @return created ca_info_t, or NULL if invalid.
- *
- * @ingroup crypto
- */
-ca_info_t *ca_info_create(const char *name, x509_t *cacert);
-
-#endif /* CA_H_ */
diff --git a/src/libstrongswan/crypto/certinfo.c b/src/libstrongswan/crypto/certinfo.c
deleted file mode 100644
index 8a125e247..000000000
--- a/src/libstrongswan/crypto/certinfo.c
+++ /dev/null
@@ -1,257 +0,0 @@
-/**
- * @file certinfo.c
- *
- * @brief Implementation of certinfo_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#include <time.h>
-#include <stdio.h>
-
-#include <library.h>
-
-#include "certinfo.h"
-
-typedef struct private_certinfo_t private_certinfo_t;
-
-/**
- * Private data of a certinfo_t object.
- */
-struct private_certinfo_t {
- /**
- * Public interface for this certificate status information object.
- */
- certinfo_t public;
-
- /**
- * Serial number of the certificate
- */
- chunk_t serialNumber;
-
- /**
- * Certificate status
- */
- cert_status_t status;
-
- /**
- * Certificate status is for one-time use only
- */
- bool once;
-
- /**
- * Time when the certificate status info was generated
- */
- time_t thisUpdate;
-
- /**
- * Time when an updated certifcate status info will be available
- */
- time_t nextUpdate;
-
- /**
- * Time of certificate revocation
- */
- time_t revocationTime;
-
- /**
- * Reason of certificate revocation
- */
- crl_reason_t revocationReason;
-};
-
-ENUM(cert_status_names, CERT_GOOD, CERT_UNTRUSTED,
- "good",
- "revoked",
- "unknown",
- "unknown",
- "untrusted",
-);
-
-ENUM(crl_reason_names, REASON_UNSPECIFIED, REASON_REMOVE_FROM_CRL,
- "unspecified",
- "key compromise",
- "ca compromise",
- "affiliation changed",
- "superseded",
- "cessation of operation",
- "certificate hold",
- "reason #7",
- "remove from crl",
-);
-
-/**
- * Implements certinfo_t.compare_serialNumber
- */
-static int compare_serialNumber(const private_certinfo_t *this, const private_certinfo_t *that)
-{
- return chunk_compare(this->serialNumber, that->serialNumber);
-}
-
-/**
- * Implements certinfo_t.equals_serialNumber
- */
-static bool equals_serialNumber(const private_certinfo_t *this, const private_certinfo_t *that)
-{
- return chunk_equals(this->serialNumber, that->serialNumber);
-}
-
-/**
- * Implements certinfo_t.get_serialNumber
- */
-static chunk_t get_serialNumber(const private_certinfo_t *this)
-{
- return this->serialNumber;
-}
-
-/**
- * Implements certinfo_t.set_status
- */
-static void set_status(private_certinfo_t *this, cert_status_t status)
-{
- this->status = status;
-}
-
-/**
- * Implements certinfo_t.get_status
- */
-static cert_status_t get_status(const private_certinfo_t *this)
-{
- return this->status;
-}
-
-/**
- * Implements certinfo_t.set_thisUpdate
- */
-static void set_thisUpdate(private_certinfo_t *this, time_t thisUpdate)
-{
- this->thisUpdate = thisUpdate;
-}
-
-/**
- * Implements certinfo_t.get_thisUpdate
- */
-static time_t get_thisUpdate(const private_certinfo_t *this)
-{
- return this->thisUpdate;
-}
-
-/**
- * Implements certinfo_t.set_nextUpdate
- */
-static void set_nextUpdate(private_certinfo_t *this, time_t nextUpdate)
-{
- this->nextUpdate = nextUpdate;
-}
-
-/**
- * Implements certinfo_t.get_nextUpdate
- */
-static time_t get_nextUpdate(const private_certinfo_t *this)
-{
- return this->nextUpdate;
-}
-
-/**
- * Implements certinfo_t.set_revocationTime
- */
-static void set_revocationTime(private_certinfo_t *this, time_t revocationTime)
-{
- this->revocationTime = revocationTime;
-}
-
-/**
- * Implements certinfo_t.get_revocationTime
- */
-static time_t get_revocationTime(const private_certinfo_t *this)
-{
- return this->revocationTime;
-}
-
-/**
- * Implements certinfo_t.set_revocationReason
- */
-static void set_revocationReason(private_certinfo_t *this, crl_reason_t reason)
-{
- this->revocationReason = reason;
-}
-
-/**
- * Implements certinfo_t.get_revocationReason
- */
-static crl_reason_t get_revocationReason(const private_certinfo_t *this)
-{
- return this->revocationReason;
-}
-
-/**
- * Implements certinfo_t.update
- */
-static void update(private_certinfo_t *this, const private_certinfo_t *that)
-{
- if (equals_serialNumber(this, that))
- {
- chunk_t this_serialNumber = this->serialNumber;
-
- *this = *that;
- this->serialNumber = this_serialNumber;
- }
-}
-
-/**
- * Implements certinfo_t.destroy
- */
-static void destroy(private_certinfo_t *this)
-{
- free(this->serialNumber.ptr);
- free(this);
-}
-
-/*
- * Described in header.
- */
-certinfo_t *certinfo_create(chunk_t serial)
-{
- private_certinfo_t *this = malloc_thing(private_certinfo_t);
-
- /* initialize */
- this->serialNumber = chunk_clone(serial);
- this->status = CERT_UNDEFINED;
- this->thisUpdate = UNDEFINED_TIME;
- this->nextUpdate = UNDEFINED_TIME;
- this->revocationTime = UNDEFINED_TIME;
- this->revocationReason = REASON_UNSPECIFIED;
-
- /* public functions */
- this->public.compare_serialNumber = (int (*) (const certinfo_t*,const certinfo_t*))compare_serialNumber;
- this->public.equals_serialNumber = (bool (*) (const certinfo_t*,const certinfo_t*))equals_serialNumber;
- this->public.get_serialNumber = (chunk_t (*) (const certinfo_t*))get_serialNumber;
- this->public.set_status = (void (*) (certinfo_t*,cert_status_t))set_status;
- this->public.get_status = (cert_status_t (*) (const certinfo_t*))get_status;
- this->public.set_thisUpdate = (void (*) (certinfo_t*,time_t))set_thisUpdate;
- this->public.get_thisUpdate = (time_t (*) (const certinfo_t*))get_thisUpdate;
- this->public.set_nextUpdate = (void (*) (certinfo_t*,time_t))set_nextUpdate;
- this->public.get_nextUpdate = (time_t (*) (const certinfo_t*))get_nextUpdate;
- this->public.set_revocationTime = (void (*) (certinfo_t*,time_t))set_revocationTime;
- this->public.get_revocationTime = (time_t (*) (const certinfo_t*))get_revocationTime;
- this->public.set_revocationReason = (void (*) (certinfo_t*, crl_reason_t))set_revocationReason;
- this->public.get_revocationReason = (crl_reason_t(*) (const certinfo_t*))get_revocationReason;
- this->public.update = (void (*) (certinfo_t*, const certinfo_t*))update;
- this->public.destroy = (void (*) (certinfo_t*))destroy;
-
- return &this->public;
-}
diff --git a/src/libstrongswan/crypto/certinfo.h b/src/libstrongswan/crypto/certinfo.h
deleted file mode 100644
index 476befda8..000000000
--- a/src/libstrongswan/crypto/certinfo.h
+++ /dev/null
@@ -1,203 +0,0 @@
-/**
- * @file certinfo.h
- *
- * @brief Interface of certinfo_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef CERTINFO_H_
-#define CERTINFO_H_
-
-typedef enum cert_status_t cert_status_t;
-typedef enum crl_reason_t crl_reason_t;
-typedef struct certinfo_t certinfo_t;
-
-#include <library.h>
-
-/**
- * RFC 2560 OCSP - certificate status
- */
-enum cert_status_t {
- CERT_GOOD = 0,
- CERT_REVOKED = 1,
- CERT_UNKNOWN = 2,
- CERT_UNDEFINED = 3,
- CERT_UNTRUSTED = 4 /* private use */
-};
-
-extern enum_name_t *cert_status_names;
-
-/**
- * RFC 2459 CRL reason codes
- */
-enum crl_reason_t {
- REASON_UNSPECIFIED = 0,
- REASON_KEY_COMPROMISE = 1,
- REASON_CA_COMPROMISE = 2,
- REASON_AFFILIATION_CHANGED = 3,
- REASON_SUPERSEDED = 4,
- REASON_CESSATION_OF_OPERATON = 5,
- REASON_CERTIFICATE_HOLD = 6,
- REASON_REMOVE_FROM_CRL = 8
-};
-
-extern enum_name_t *crl_reason_names;
-
-/**
- * @brief X.509 certificate status information
- *
- * @ingroup transforms
- */
-struct certinfo_t {
-
- /**
- * @brief Check if both certinfo objects have the same serialNumber.
- *
- * @param this calling object
- * @param that second certinfo_t object
- * @return TRUE if the same serialNumber
- */
- bool (*equals_serialNumber) (const certinfo_t *this, const certinfo_t *that);
-
- /**
- * @brief Compares two serial numbers.
- *
- * @param this calling object
- * @param that second certinfo_t object
- * @return negative if this is smaller than that
- * zero if this equals that
- * positive if this is greater than that
- */
- int (*compare_serialNumber) (const certinfo_t *this, const certinfo_t *that);
-
- /**
- * @brief Get serial number.
- *
- * @param this calling object
- * @return serialNumber
- */
- chunk_t (*get_serialNumber) (const certinfo_t *this);
-
- /**
- * @brief Set certificate status.
- *
- * @param this calling object
- * @param status status
- */
- void (*set_status) (certinfo_t *this, cert_status_t status);
-
- /**
- * @brief Get certificate status.
- *
- * @param this calling object
- * @return status
- */
- cert_status_t (*get_status) (const certinfo_t *this);
-
- /**
- * @brief Set thisUpdate.
- *
- * @param this calling object
- * @param thisUpdate thisUpdate
- */
- void (*set_thisUpdate) (certinfo_t *this, time_t thisUpdate);
-
- /**
- * @brief Get thisUpdate.
- *
- * @param this calling object
- * @return thisUpdate
- */
- time_t (*get_thisUpdate) (const certinfo_t *this);
-
- /**
- * @brief Set nextUpdate.
- *
- * @param this calling object
- * @param nextUpdate
- */
- void (*set_nextUpdate) (certinfo_t *this, time_t nextUpdate);
-
- /**
- * @brief Get nextUpdate.
- *
- * @param this calling object
- * @return nextUpdate
- */
- time_t (*get_nextUpdate) (const certinfo_t *this);
-
- /**
- * @brief Set revocationTime.
- *
- * @param this calling object
- * @param revocationTime revocationTime
- */
- void (*set_revocationTime) (certinfo_t *this, time_t revocationTime);
-
- /**
- * @brief Get revocationTime.
- *
- * @param this calling object
- * @return revocationTime
- */
- time_t (*get_revocationTime) (const certinfo_t *this);
-
- /**
- * @brief Set revocationReason.
- *
- * @param this calling object
- * @param reason revocationReason
- */
- void (*set_revocationReason) (certinfo_t *this, crl_reason_t reason);
-
- /**
- * @brief Get revocationReason.
- *
- * @param this calling object
- * @return revocationReason
- */
- crl_reason_t (*get_revocationReason) (const certinfo_t *this);
-
- /**
- * @brief Set revocationReason.
- *
- * @param this calling object to be updated
- * @param that object containing updated information
- */
- void (*update) (certinfo_t *this, const certinfo_t *that);
-
- /**
- * @brief Destroys the certinfo_t object.
- *
- * @param this certinfo_t to destroy
- */
- void (*destroy) (certinfo_t *this);
-
-};
-
-/**
- * @brief Create a certinfo_t object.
- *
- * @param serial chunk serial number of the certificate
- * @return created certinfo_t object
- *
- * @ingroup transforms
- */
-certinfo_t *certinfo_create(chunk_t serial);
-
-#endif /* CERTINFO_H_ */
diff --git a/src/libstrongswan/crypto/crl.c b/src/libstrongswan/crypto/crl.c
deleted file mode 100755
index ab23bb9ec..000000000
--- a/src/libstrongswan/crypto/crl.c
+++ /dev/null
@@ -1,536 +0,0 @@
-/**
- * @file crl.c
- *
- * @brief Implementation of crl_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: crl.c 3355 2007-11-20 12:06:40Z martin $
- */
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <library.h>
-#include <debug.h>
-#include <asn1/oid.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-#include "certinfo.h"
-#include "x509.h"
-#include "crl.h"
-
-#define CRL_WARNING_INTERVAL 7 /* days */
-
-/* access structure for a revoked certificate */
-
-typedef struct revokedCert_t revokedCert_t;
-
-struct revokedCert_t {
- chunk_t userCertificate;
- time_t revocationDate;
- crl_reason_t revocationReason;
-};
-
-typedef struct private_crl_t private_crl_t;
-
-/**
- * Private data of a crl_t object.
- */
-struct private_crl_t {
- /**
- * Public interface for this crl.
- */
- crl_t public;
-
- /**
- * Time when crl was installed
- */
- time_t installed;
-
- /**
- * List of crlDistributionPoints
- */
- linked_list_t *crlDistributionPoints;
-
- /**
- * X.509 crl in DER format
- */
- chunk_t certificateList;
-
- /**
- * X.509 crl body over which signature is computed
- */
- chunk_t tbsCertList;
-
- /**
- * Version of the X.509 crl
- */
- u_int version;
-
- /**
- * Signature algorithm
- */
- int sigAlg;
-
- /**
- * ID representing the crl issuer
- */
- identification_t *issuer;
-
- /**
- * CRL number
- */
- chunk_t crlNumber;
-
- /**
- * Time when the crl was generated
- */
- time_t thisUpdate;
-
- /**
- * Time when an update crl will be available
- */
- time_t nextUpdate;
-
- /**
- * List of identification_t's representing subjectAltNames
- */
- linked_list_t *revokedCertificates;
-
- /**
- * Authority Key Identifier
- */
- chunk_t authKeyID;
-
- /**
- * Authority Key Serial Number
- */
- chunk_t authKeySerialNumber;
-
- /**
- * Signature algorithm (must be identical to sigAlg)
- */
- int algorithm;
-
- /**
- * Signature
- */
- chunk_t signature;
-};
-
-/**
- * ASN.1 definition of an X.509 certificate revocation list
- */
-static const asn1Object_t crlObjects[] = {
- { 0, "certificateList", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "tbsCertList", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "version", ASN1_INTEGER, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 3 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 4 */
- { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 2, "thisUpdate", ASN1_EOC, ASN1_RAW }, /* 6 */
- { 2, "nextUpdate", ASN1_EOC, ASN1_RAW }, /* 7 */
- { 2, "revokedCertificates", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 8 */
- { 3, "certList", ASN1_SEQUENCE, ASN1_NONE }, /* 9 */
- { 4, "userCertificate", ASN1_INTEGER, ASN1_BODY }, /* 10 */
- { 4, "revocationDate", ASN1_EOC, ASN1_RAW }, /* 11 */
- { 4, "crlEntryExtensions", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 12 */
- { 5, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
- { 6, "extnID", ASN1_OID, ASN1_BODY }, /* 14 */
- { 6, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 15 */
- { 6, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 16 */
- { 4, "end opt or loop", ASN1_EOC, ASN1_END }, /* 17 */
- { 2, "end opt or loop", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "optional extensions", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 19 */
- { 3, "crlExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_DEF |
- ASN1_BODY }, /* 23 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
- { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 28 */
- };
-
-#define CRL_OBJ_CERTIFICATE_LIST 0
-#define CRL_OBJ_TBS_CERT_LIST 1
-#define CRL_OBJ_VERSION 2
-#define CRL_OBJ_SIG_ALG 4
-#define CRL_OBJ_ISSUER 5
-#define CRL_OBJ_THIS_UPDATE 6
-#define CRL_OBJ_NEXT_UPDATE 7
-#define CRL_OBJ_USER_CERTIFICATE 10
-#define CRL_OBJ_REVOCATION_DATE 11
-#define CRL_OBJ_CRL_ENTRY_EXTN_ID 14
-#define CRL_OBJ_CRL_ENTRY_CRITICAL 15
-#define CRL_OBJ_CRL_ENTRY_EXTN_VALUE 16
-#define CRL_OBJ_EXTN_ID 22
-#define CRL_OBJ_CRITICAL 23
-#define CRL_OBJ_EXTN_VALUE 24
-#define CRL_OBJ_ALGORITHM 27
-#define CRL_OBJ_SIGNATURE 28
-#define CRL_OBJ_ROOF 29
-
-/**
- * Parses a CRL revocation reason code
- */
-static crl_reason_t parse_crl_reasonCode(chunk_t object)
-{
- crl_reason_t reason = REASON_UNSPECIFIED;
-
- if (*object.ptr == ASN1_ENUMERATED && asn1_length(&object) == 1)
- {
- reason = *object.ptr;
- }
- DBG2(" '%N'", crl_reason_names, reason);
-
- return reason;
-}
-
-/**
- * Parses an X.509 Certificate Revocation List (CRL)
- */
-bool parse_x509crl(chunk_t blob, u_int level0, private_crl_t *crl)
-{
- asn1_ctx_t ctx;
- bool critical;
- chunk_t extnID;
- chunk_t userCertificate = chunk_empty;
- revokedCert_t *revokedCert = NULL;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < CRL_OBJ_ROOF)
- {
- if (!extract_object(crlObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- /* those objects which will parsed further need the next higher level */
- level++;
-
- switch (objectID)
- {
- case CRL_OBJ_CERTIFICATE_LIST:
- crl->certificateList = object;
- break;
- case CRL_OBJ_TBS_CERT_LIST:
- crl->tbsCertList = object;
- break;
- case CRL_OBJ_VERSION:
- crl->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
- DBG2(" v%d", crl->version);
- break;
- case CRL_OBJ_SIG_ALG:
- crl->sigAlg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case CRL_OBJ_ISSUER:
- crl->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", crl->issuer);
- break;
- case CRL_OBJ_THIS_UPDATE:
- crl->thisUpdate = parse_time(object, level);
- break;
- case CRL_OBJ_NEXT_UPDATE:
- crl->nextUpdate = parse_time(object, level);
- break;
- case CRL_OBJ_USER_CERTIFICATE:
- userCertificate = object;
- break;
- case CRL_OBJ_REVOCATION_DATE:
- revokedCert = malloc_thing(revokedCert_t);
- revokedCert->userCertificate = userCertificate;
- revokedCert->revocationDate = parse_time(object, level);
- revokedCert->revocationReason = REASON_UNSPECIFIED;
- crl->revokedCertificates->insert_last(crl->revokedCertificates, (void *)revokedCert);
- break;
- case CRL_OBJ_CRL_ENTRY_EXTN_ID:
- case CRL_OBJ_EXTN_ID:
- extnID = object;
- break;
- case CRL_OBJ_CRL_ENTRY_CRITICAL:
- case CRL_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG2(" %s",(critical)?"TRUE":"FALSE");
- break;
- case CRL_OBJ_CRL_ENTRY_EXTN_VALUE:
- case CRL_OBJ_EXTN_VALUE:
- {
- int extn_oid = known_oid(extnID);
-
- if (revokedCert && extn_oid == OID_CRL_REASON_CODE)
- {
- revokedCert->revocationReason = parse_crl_reasonCode(object);
- }
- else if (extn_oid == OID_AUTHORITY_KEY_ID)
- {
- x509_parse_authorityKeyIdentifier(object, level,
- &crl->authKeyID, &crl->authKeySerialNumber);
- }
- else if (extn_oid == OID_CRL_NUMBER)
- {
- if (!parse_asn1_simple_object(&object, ASN1_INTEGER, level, "crlNumber"))
- {
- return FALSE;
- }
- crl->crlNumber = object;
- }
- }
- break;
- case CRL_OBJ_ALGORITHM:
- crl->algorithm = parse_algorithmIdentifier(object, level, NULL);
- if (crl->algorithm != crl->sigAlg)
- {
- DBG1(" signature algorithms do not agree");
- return FALSE;
- }
- break;
- case CRL_OBJ_SIGNATURE:
- crl->signature = object;
- break;
- default:
- break;
- }
- objectID++;
- }
- time(&crl->installed);
- return TRUE;
-}
-
-/**
- * Implements crl_t.is_valid
- */
-static bool is_valid(const private_crl_t *this)
-{
- time_t current_time = time(NULL);
-
- DBG2(" this update : %T", &this->thisUpdate);
- DBG2(" current time: %T", &current_time);
- DBG2(" next update: %T", &this->nextUpdate);
-
- return current_time < this->nextUpdate;
-}
-
-/**
- * Implements crl_t.get_issuer
- */
-static identification_t *get_issuer(const private_crl_t *this)
-{
- return this->issuer;
-}
-
-/**
- * Implements crl_t.equals_issuer
- */
-static bool equals_issuer(const private_crl_t *this, const private_crl_t *other)
-{
- return (this->authKeyID.ptr)
- ? chunk_equals(this->authKeyID, other->authKeyID)
- : (this->issuer->equals(this->issuer, other->issuer)
- && chunk_equals_or_null(this->authKeySerialNumber, other->authKeySerialNumber));
-}
-
-/**
- * Implements crl_t.is_issuer
- */
-static bool is_issuer(const private_crl_t *this, const x509_t *issuer)
-{
- return (this->authKeyID.ptr)
- ? chunk_equals(this->authKeyID, issuer->get_subjectKeyID(issuer))
- : (this->issuer->equals(this->issuer, issuer->get_subject(issuer))
- && chunk_equals_or_null(this->authKeySerialNumber, issuer->get_serialNumber(issuer)));
-}
-
-/**
- * Implements crl_t.is_newer
- */
-static bool is_newer(const private_crl_t *this, const private_crl_t *other)
-{
- return (this->nextUpdate > other->nextUpdate);
-}
-
-/**
- * Implements crl_t.verify
- */
-static bool verify(const private_crl_t *this, const rsa_public_key_t *signer)
-{
- hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->algorithm);
-
- if (algorithm == HASH_UNKNOWN)
- {
- DBG1(" unknown signature algorithm");
- return FALSE;
- }
- return signer->verify_emsa_pkcs1_signature(signer, algorithm, this->tbsCertList, this->signature) == SUCCESS;
-}
-
-/**
- * Implements crl_t.get_status
- */
-static void get_status(const private_crl_t *this, certinfo_t *certinfo)
-{
- chunk_t serialNumber = certinfo->get_serialNumber(certinfo);
- iterator_t *iterator;
- revokedCert_t *revokedCert;
-
- certinfo->set_nextUpdate(certinfo, this->nextUpdate);
- certinfo->set_status(certinfo, CERT_GOOD);
-
- iterator = this->revokedCertificates->create_iterator(this->revokedCertificates, TRUE);
- while (iterator->iterate(iterator, (void**)&revokedCert))
- {
- if (chunk_equals(serialNumber, revokedCert->userCertificate))
- {
- certinfo->set_status(certinfo, CERT_REVOKED);
- certinfo->set_revocationTime(certinfo, revokedCert->revocationDate);
- certinfo->set_revocationReason(certinfo, revokedCert->revocationReason);
- break;
- }
- }
- iterator->destroy(iterator);
-}
-
-/**
- * Implements crl_t.write_to_file.
- */
-static bool write_to_file(private_crl_t *this, const char *path, mode_t mask, bool force)
-{
- return chunk_write(this->certificateList, path, "crl", mask, force);
-}
-
-/**
- * Implements crl_t.destroy
- */
-static void destroy(private_crl_t *this)
-{
- this->revokedCertificates->destroy_function(this->revokedCertificates, free);
- this->crlDistributionPoints->destroy_offset(this->crlDistributionPoints,
- offsetof(identification_t, destroy));
- DESTROY_IF(this->issuer);
- free(this->certificateList.ptr);
- free(this);
-}
-
-/**
- * Implementation of crl_t.list.
- */
-static void list(private_crl_t *this, FILE* out, bool utc)
-{
- time_t now;
-
- now = time(NULL);
-
- fprintf(out, "%#T, revoked certs: %d\n", &this->installed, utc,
- this->revokedCertificates->get_count(this->revokedCertificates));
- fprintf(out, " issuer: '%D'\n", this->issuer);
- if (this->crlNumber.ptr)
- {
- fprintf(out, " crlnumber: %#B\n", &this->crlNumber);
- }
- fprintf(out, " updates: this %#T\n", &this->thisUpdate, utc);
- fprintf(out, " next %#T ", &this->nextUpdate, utc);
- if (this->nextUpdate == UNDEFINED_TIME)
- {
- fprintf(out, "ok (expires never)\n");
- }
- else if (now > this->nextUpdate)
- {
- fprintf(out, "expired (%#V ago)\n", &now, &this->nextUpdate);
- }
- else if (now > this->nextUpdate - CRL_WARNING_INTERVAL * 60 * 60 * 24)
- {
- fprintf(out, "ok (expires in %#V)\n", &now, &this->nextUpdate);
- }
- else
- {
- fprintf(out, "ok\n");
- }
- if (this->authKeyID.ptr)
- {
- fprintf(out, " authkey: %#B\n", &this->authKeyID);
- }
- if (this->authKeySerialNumber.ptr)
- {
- fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber);
- }
-}
-
-/*
- * Described in header.
- */
-crl_t *crl_create_from_chunk(chunk_t chunk)
-{
- private_crl_t *this = malloc_thing(private_crl_t);
-
- /* initialize */
- this->crlDistributionPoints = linked_list_create();
- this->tbsCertList = chunk_empty;
- this->issuer = NULL;
- this->crlNumber = chunk_empty;
- this->revokedCertificates = linked_list_create();
- this->authKeyID = chunk_empty;
- this->authKeySerialNumber = chunk_empty;
-
- /* public functions */
- this->public.get_issuer = (identification_t* (*) (const crl_t*))get_issuer;
- this->public.equals_issuer = (bool (*) (const crl_t*,const crl_t*))equals_issuer;
- this->public.is_issuer = (bool (*) (const crl_t*,const x509_t*))is_issuer;
- this->public.is_valid = (bool (*) (const crl_t*))is_valid;
- this->public.is_newer = (bool (*) (const crl_t*,const crl_t*))is_newer;
- this->public.verify = (bool (*) (const crl_t*,const rsa_public_key_t*))verify;
- this->public.get_status = (void (*) (const crl_t*,certinfo_t*))get_status;
- this->public.write_to_file = (bool (*) (const crl_t*,const char*,mode_t,bool))write_to_file;
- this->public.list = (void(*)(crl_t*, FILE* out, bool utc))list;
- this->public.destroy = (void (*) (crl_t*))destroy;
-
- if (!parse_x509crl(chunk, 0, this))
- {
- destroy(this);
- return NULL;
- }
-
- return &this->public;
-}
-
-/*
- * Described in header.
- */
-crl_t *crl_create_from_file(const char *filename)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
-
- if (!pem_asn1_load_file(filename, NULL, "crl", &chunk, &pgp))
- {
- return NULL;
- }
- return crl_create_from_chunk(chunk);
-}
diff --git a/src/libstrongswan/crypto/crl.h b/src/libstrongswan/crypto/crl.h
deleted file mode 100755
index bcf031dd4..000000000
--- a/src/libstrongswan/crypto/crl.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/**
- * @file crl.h
- *
- * @brief Interface of crl_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Andreas Steffen
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: crl.h 3300 2007-10-12 21:53:18Z andreas $
- */
-
-#ifndef CRL_H_
-#define CRL_H_
-
-typedef struct crl_t crl_t;
-
-#include <library.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <crypto/certinfo.h>
-#include <utils/identification.h>
-#include <utils/iterator.h>
-
-/**
- * @brief X.509 certificate revocation list
- *
- * @b Constructors:
- * - crl_create_from_chunk()
- * - crl_create_from_file()
- *
- * @ingroup transforms
- */
-struct crl_t {
-
- /**
- * @brief Get the crl's issuer ID.
- *
- * The resulting ID is always a identification_t
- * of type ID_DER_ASN1_DN.
- *
- * @param this calling object
- * @return issuers ID
- */
- identification_t *(*get_issuer) (const crl_t *this);
-
- /**
- * @brief Check if both crls have the same issuer.
- *
- * @param this calling object
- * @param other other crl
- * @return TRUE if the same issuer
- */
- bool (*equals_issuer) (const crl_t *this, const crl_t *other);
-
- /**
- * @brief Check if ia candidate cert is the issuer of the crl
- *
- * @param this calling object
- * @param issuer candidate issuer of the crl
- * @return TRUE if issuer
- */
- bool (*is_issuer) (const crl_t *this, const x509_t *issuer);
-
- /**
- * @brief Checks the validity interval of the crl
- *
- * @param this calling object
- * @return TRUE if the crl is valid
- */
- bool (*is_valid) (const crl_t *this);
-
- /**
- * @brief Checks if this crl is newer (thisUpdate) than the other crl
- *
- * @param this calling object
- * @param other other crl object
- * @return TRUE if this was issued more recently than other
- */
- bool (*is_newer) (const crl_t *this, const crl_t *other);
-
- /**
- * @brief Check if a crl is trustworthy.
- *
- * @param this calling object
- * @param signer signer's RSA public key
- * @return TRUE if crl is trustworthy
- */
- bool (*verify) (const crl_t *this, const rsa_public_key_t *signer);
-
- /**
- * @brief Get the certificate status
- *
- * @param this calling object
- * @param certinfo certinfo is updated
- */
- void (*get_status) (const crl_t *this, certinfo_t *certinfo);
-
- /**
- * @brief Log the info of this CRL to out.
- *
- * @param this calling object
- * @param out stream to write to
- * @param utc TRUE for UTC, FALSE for local time
- */
- void (*list)(crl_t *this, FILE* out, bool utc);
-
- /**
- * @brief Write a der-encoded crl to a file
- *
- * @param this calling object
- * @param path path where the file is to be stored
- * @param mask file access control rights
- * @param force overwrite the file if it already exists
- * @return TRUE if successfully written
- */
- bool (*write_to_file) (const crl_t *this, const char *path, mode_t mask, bool force);
-
- /**
- * @brief Destroys the crl.
- *
- * @param this crl to destroy
- */
- void (*destroy) (crl_t *this);
-};
-
-/**
- * @brief Read a x509 crl from a DER encoded blob.
- *
- * @param chunk chunk containing DER encoded data
- * @return created crl_t, or NULL if invalid.
- *
- * @ingroup transforms
- */
-crl_t *crl_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Read a x509 crl from a DER encoded file.
- *
- * @param filename file containing DER encoded data
- * @return created crl_t, or NULL if invalid.
- *
- * @ingroup transforms
- */
-crl_t *crl_create_from_file(const char *filename);
-
-#endif /* CRL_H_ */
diff --git a/src/libstrongswan/crypto/crypters/aes_cbc_crypter.c b/src/libstrongswan/crypto/crypters/aes_cbc_crypter.c
deleted file mode 100644
index 947188af3..000000000
--- a/src/libstrongswan/crypto/crypters/aes_cbc_crypter.c
+++ /dev/null
@@ -1,1620 +0,0 @@
-/**
- * @file aes_cbc_crypter.c
- *
- * @brief Implementation of aes_cbc_crypter_t
- *
- */
-
- /*
- * Copyright (C) 2001 Dr B. R. Gladman <brg@gladman.uk.net>
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#include "aes_cbc_crypter.h"
-
-
-
-/*
- * The number of key schedule words for different block and key lengths
- * allowing for method of computation which requires the length to be a
- * multiple of the key length. This version of AES implementation supports
- * all three keylengths 16, 24 and 32 bytes!
- *
- * Nk = 4 6 8
- * -------------
- * Nb = 4 | 60 60 64
- * 6 | 96 90 96
- * 8 | 120 120 120
- */
-#define AES_KS_LENGTH 120
-#define AES_RC_LENGTH 29
-
-#define AES_BLOCK_SIZE 16
-
-typedef struct private_aes_cbc_crypter_t private_aes_cbc_crypter_t;
-
-/**
- * @brief Class implementing the AES symmetric encryption algorithm.
- *
- * @ingroup crypters
- */
-struct private_aes_cbc_crypter_t {
-
- /**
- * Public part of this class.
- */
- aes_cbc_crypter_t public;
-
- /**
- * Number of words in the key input block.
- */
- u_int32_t aes_Nkey;
-
- /**
- * The number of cipher rounds.
- */
- u_int32_t aes_Nrnd;
-
- /**
- * The encryption key schedule.
- */
- u_int32_t aes_e_key[AES_KS_LENGTH];
-
- /**
- * The decryption key schedule.
- */
- u_int32_t aes_d_key[AES_KS_LENGTH];
-
- /**
- * Key size of this AES cypher object.
- */
- u_int32_t key_size;
-
- /**
- * Decrypts a block.
- *
- * No memory gets allocated.
- *
- * @param this calling object
- * @param[in] in_blk block to decrypt
- * @param[out] out_blk decrypted data are written to this location
- */
- void (*decrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
-
- /**
- * Encrypts a block.
- *
- * No memory gets allocated.
- *
- * @param this calling object
- * @param[in] in_blk block to encrypt
- * @param[out] out_blk encrypted data are written to this location
- */
- void (*encrypt_block) (const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[]);
-};
-
-
-/* ugly macro stuff */
-
-/* 1. Define UNROLL for full loop unrolling in encryption and decryption.
- * 2. Define PARTIAL_UNROLL to unroll two loops in encryption and decryption.
- * 3. Define FIXED_TABLES for compiled rather than dynamic tables.
- * 4. Define FF_TABLES to use tables for field multiplies and inverses.
- * Do not enable this without understanding stack space requirements.
- * 5. Define ARRAYS to use arrays to hold the local state block. If this
- * is not defined, individually declared 32-bit words are used.
- * 6. Define FAST_VARIABLE if a high speed variable block implementation
- * is needed (essentially three separate fixed block size code sequences)
- * 7. Define either ONE_TABLE or FOUR_TABLES for a fast table driven
- * version using 1 table (2 kbytes of table space) or 4 tables (8
- * kbytes of table space) for higher speed.
- * 8. Define either ONE_LR_TABLE or FOUR_LR_TABLES for a further speed
- * increase by using tables for the last rounds but with more table
- * space (2 or 8 kbytes extra).
- * 9. If neither ONE_TABLE nor FOUR_TABLES is defined, a compact but
- * slower version is provided.
- * 10. If fast decryption key scheduling is needed define ONE_IM_TABLE
- * or FOUR_IM_TABLES for higher speed (2 or 8 kbytes extra).
- */
-
-#define UNROLL
-//#define PARTIAL_UNROLL
-
-#define FIXED_TABLES
-//#define FF_TABLES
-//#define ARRAYS
-#define FAST_VARIABLE
-
-//#define ONE_TABLE
-#define FOUR_TABLES
-
-//#define ONE_LR_TABLE
-#define FOUR_LR_TABLES
-
-//#define ONE_IM_TABLE
-#define FOUR_IM_TABLES
-
-#if defined(UNROLL) && defined (PARTIAL_UNROLL)
-#error both UNROLL and PARTIAL_UNROLL are defined
-#endif
-
-#if defined(ONE_TABLE) && defined (FOUR_TABLES)
-#error both ONE_TABLE and FOUR_TABLES are defined
-#endif
-
-#if defined(ONE_LR_TABLE) && defined (FOUR_LR_TABLES)
-#error both ONE_LR_TABLE and FOUR_LR_TABLES are defined
-#endif
-
-#if defined(ONE_IM_TABLE) && defined (FOUR_IM_TABLES)
-#error both ONE_IM_TABLE and FOUR_IM_TABLES are defined
-#endif
-
-#if defined(AES_BLOCK_SIZE) && AES_BLOCK_SIZE != 16 && AES_BLOCK_SIZE != 24 && AES_BLOCK_SIZE != 32
-#error an illegal block size has been specified
-#endif
-
-/**
- * Rotates bytes within words by n positions, moving bytes
- * to higher index positions with wrap around into low positions.
- */
-#define upr(x,n) (((x) << 8 * (n)) | ((x) >> (32 - 8 * (n))))
-/**
- * Moves bytes by n positions to higher index positions in
- * words but without wrap around.
- */
-#define ups(x,n) ((x) << 8 * (n))
-
-/**
- * Extracts a byte from a word.
- */
-#define bval(x,n) ((unsigned char)((x) >> 8 * (n)))
-#define bytes2word(b0, b1, b2, b3) \
- ((u_int32_t)(b3) << 24 | (u_int32_t)(b2) << 16 | (u_int32_t)(b1) << 8 | (b0))
-
-
-/* little endian processor without data alignment restrictions: AES_LE_OK */
-/* original code: i386 */
-#if defined(i386) || defined(_I386) || defined(__i386__) || defined(__i386)
-#define AES_LE_OK 1
-/* added (tested): alpha --jjo */
-#elif defined(__alpha__)|| defined (__alpha)
-#define AES_LE_OK 1
-/* added (tested): ia64 --jjo */
-#elif defined(__ia64__)|| defined (__ia64)
-#define AES_LE_OK 1
-#endif
-
-#ifdef AES_LE_OK
-/* little endian processor without data alignment restrictions */
-#define word_in(x) *(u_int32_t*)(x)
-#define const_word_in(x) *(const u_int32_t*)(x)
-#define word_out(x,v) *(u_int32_t*)(x) = (v)
-#define const_word_out(x,v) *(const u_int32_t*)(x) = (v)
-#else
-/* slower but generic big endian or with data alignment restrictions */
-/* some additional "const" touches to stop "gcc -Wcast-qual" complains --jjo */
-#define word_in(x) ((u_int32_t)(((unsigned char *)(x))[0])|((u_int32_t)(((unsigned char *)(x))[1])<<8)|((u_int32_t)(((unsigned char *)(x))[2])<<16)|((u_int32_t)(((unsigned char *)(x))[3])<<24))
-#define const_word_in(x) ((const u_int32_t)(((const unsigned char *)(x))[0])|((const u_int32_t)(((const unsigned char *)(x))[1])<<8)|((const u_int32_t)(((const unsigned char *)(x))[2])<<16)|((const u_int32_t)(((const unsigned char *)(x))[3])<<24))
-#define word_out(x,v) ((unsigned char *)(x))[0]=(v),((unsigned char *)(x))[1]=((v)>>8),((unsigned char *)(x))[2]=((v)>>16),((unsigned char *)(x))[3]=((v)>>24)
-#define const_word_out(x,v) ((const unsigned char *)(x))[0]=(v),((const unsigned char *)(x))[1]=((v)>>8),((const unsigned char *)(x))[2]=((v)>>16),((const unsigned char *)(x))[3]=((v)>>24)
-#endif
-
-// Disable at least some poor combinations of options
-
-#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
-#define FIXED_TABLES
-#undef UNROLL
-#undef ONE_LR_TABLE
-#undef FOUR_LR_TABLES
-#undef ONE_IM_TABLE
-#undef FOUR_IM_TABLES
-#elif !defined(FOUR_TABLES)
-#ifdef FOUR_LR_TABLES
-#undef FOUR_LR_TABLES
-#define ONE_LR_TABLE
-#endif
-#ifdef FOUR_IM_TABLES
-#undef FOUR_IM_TABLES
-#define ONE_IM_TABLE
-#endif
-#elif !defined(AES_BLOCK_SIZE)
-#if defined(UNROLL)
-#define PARTIAL_UNROLL
-#undef UNROLL
-#endif
-#endif
-
-// the finite field modular polynomial and elements
-
-#define ff_poly 0x011b
-#define ff_hi 0x80
-
-// multiply four bytes in GF(2^8) by 'x' {02} in parallel
-
-#define m1 0x80808080
-#define m2 0x7f7f7f7f
-#define m3 0x0000001b
-#define FFmulX(x) ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * m3))
-
-// The following defines provide alternative definitions of FFmulX that might
-// give improved performance if a fast 32-bit multiply is not available. Note
-// that a temporary variable u needs to be defined where FFmulX is used.
-
-// #define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
-// #define m4 0x1b1b1b1b
-// #define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
-
-// perform column mix operation on four bytes in parallel
-
-#define fwd_mcol(x) (f2 = FFmulX(x), f2 ^ upr(x ^ f2,3) ^ upr(x,2) ^ upr(x,1))
-
-#if defined(FIXED_TABLES)
-
-// the S-Box table
-
-static const unsigned char s_box[256] =
-{
- 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
- 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
- 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
- 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
- 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
- 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
- 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
- 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
- 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
- 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
- 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
- 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
- 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
- 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
- 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
- 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
- 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
- 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
- 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
- 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
- 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
- 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
- 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
- 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
- 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
- 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
- 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
- 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
- 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
- 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
- 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
- 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-};
-
-// the inverse S-Box table
-
-static const unsigned char inv_s_box[256] =
-{
- 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
- 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
- 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
- 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
- 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
- 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
- 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
- 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
- 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
- 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
- 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
- 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
- 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
- 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
- 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
- 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
- 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
- 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
- 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
- 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
- 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
- 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
- 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
- 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
- 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
- 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
- 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
- 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
- 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
- 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
- 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
- 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-};
-
-#define w0(p) 0x000000##p
-
-// Number of elements required in this table for different
-// block and key lengths is:
-//
-// Nk = 4 6 8
-// ----------
-// Nb = 4 | 10 8 7
-// 6 | 19 12 11
-// 8 | 29 19 14
-//
-// this table can be a table of bytes if the key schedule
-// code is adjusted accordingly
-
-static const u_int32_t rcon_tab[29] =
-{
- w0(01), w0(02), w0(04), w0(08),
- w0(10), w0(20), w0(40), w0(80),
- w0(1b), w0(36), w0(6c), w0(d8),
- w0(ab), w0(4d), w0(9a), w0(2f),
- w0(5e), w0(bc), w0(63), w0(c6),
- w0(97), w0(35), w0(6a), w0(d4),
- w0(b3), w0(7d), w0(fa), w0(ef),
- w0(c5)
-};
-
-#undef w0
-
-#define r0(p,q,r,s) 0x##p##q##r##s
-#define r1(p,q,r,s) 0x##q##r##s##p
-#define r2(p,q,r,s) 0x##r##s##p##q
-#define r3(p,q,r,s) 0x##s##p##q##r
-#define w0(p) 0x000000##p
-#define w1(p) 0x0000##p##00
-#define w2(p) 0x00##p##0000
-#define w3(p) 0x##p##000000
-
-#if defined(FIXED_TABLES) && (defined(ONE_TABLE) || defined(FOUR_TABLES))
-
-// data for forward tables (other than last round)
-
-#define f_table \
- r(a5,63,63,c6), r(84,7c,7c,f8), r(99,77,77,ee), r(8d,7b,7b,f6),\
- r(0d,f2,f2,ff), r(bd,6b,6b,d6), r(b1,6f,6f,de), r(54,c5,c5,91),\
- r(50,30,30,60), r(03,01,01,02), r(a9,67,67,ce), r(7d,2b,2b,56),\
- r(19,fe,fe,e7), r(62,d7,d7,b5), r(e6,ab,ab,4d), r(9a,76,76,ec),\
- r(45,ca,ca,8f), r(9d,82,82,1f), r(40,c9,c9,89), r(87,7d,7d,fa),\
- r(15,fa,fa,ef), r(eb,59,59,b2), r(c9,47,47,8e), r(0b,f0,f0,fb),\
- r(ec,ad,ad,41), r(67,d4,d4,b3), r(fd,a2,a2,5f), r(ea,af,af,45),\
- r(bf,9c,9c,23), r(f7,a4,a4,53), r(96,72,72,e4), r(5b,c0,c0,9b),\
- r(c2,b7,b7,75), r(1c,fd,fd,e1), r(ae,93,93,3d), r(6a,26,26,4c),\
- r(5a,36,36,6c), r(41,3f,3f,7e), r(02,f7,f7,f5), r(4f,cc,cc,83),\
- r(5c,34,34,68), r(f4,a5,a5,51), r(34,e5,e5,d1), r(08,f1,f1,f9),\
- r(93,71,71,e2), r(73,d8,d8,ab), r(53,31,31,62), r(3f,15,15,2a),\
- r(0c,04,04,08), r(52,c7,c7,95), r(65,23,23,46), r(5e,c3,c3,9d),\
- r(28,18,18,30), r(a1,96,96,37), r(0f,05,05,0a), r(b5,9a,9a,2f),\
- r(09,07,07,0e), r(36,12,12,24), r(9b,80,80,1b), r(3d,e2,e2,df),\
- r(26,eb,eb,cd), r(69,27,27,4e), r(cd,b2,b2,7f), r(9f,75,75,ea),\
- r(1b,09,09,12), r(9e,83,83,1d), r(74,2c,2c,58), r(2e,1a,1a,34),\
- r(2d,1b,1b,36), r(b2,6e,6e,dc), r(ee,5a,5a,b4), r(fb,a0,a0,5b),\
- r(f6,52,52,a4), r(4d,3b,3b,76), r(61,d6,d6,b7), r(ce,b3,b3,7d),\
- r(7b,29,29,52), r(3e,e3,e3,dd), r(71,2f,2f,5e), r(97,84,84,13),\
- r(f5,53,53,a6), r(68,d1,d1,b9), r(00,00,00,00), r(2c,ed,ed,c1),\
- r(60,20,20,40), r(1f,fc,fc,e3), r(c8,b1,b1,79), r(ed,5b,5b,b6),\
- r(be,6a,6a,d4), r(46,cb,cb,8d), r(d9,be,be,67), r(4b,39,39,72),\
- r(de,4a,4a,94), r(d4,4c,4c,98), r(e8,58,58,b0), r(4a,cf,cf,85),\
- r(6b,d0,d0,bb), r(2a,ef,ef,c5), r(e5,aa,aa,4f), r(16,fb,fb,ed),\
- r(c5,43,43,86), r(d7,4d,4d,9a), r(55,33,33,66), r(94,85,85,11),\
- r(cf,45,45,8a), r(10,f9,f9,e9), r(06,02,02,04), r(81,7f,7f,fe),\
- r(f0,50,50,a0), r(44,3c,3c,78), r(ba,9f,9f,25), r(e3,a8,a8,4b),\
- r(f3,51,51,a2), r(fe,a3,a3,5d), r(c0,40,40,80), r(8a,8f,8f,05),\
- r(ad,92,92,3f), r(bc,9d,9d,21), r(48,38,38,70), r(04,f5,f5,f1),\
- r(df,bc,bc,63), r(c1,b6,b6,77), r(75,da,da,af), r(63,21,21,42),\
- r(30,10,10,20), r(1a,ff,ff,e5), r(0e,f3,f3,fd), r(6d,d2,d2,bf),\
- r(4c,cd,cd,81), r(14,0c,0c,18), r(35,13,13,26), r(2f,ec,ec,c3),\
- r(e1,5f,5f,be), r(a2,97,97,35), r(cc,44,44,88), r(39,17,17,2e),\
- r(57,c4,c4,93), r(f2,a7,a7,55), r(82,7e,7e,fc), r(47,3d,3d,7a),\
- r(ac,64,64,c8), r(e7,5d,5d,ba), r(2b,19,19,32), r(95,73,73,e6),\
- r(a0,60,60,c0), r(98,81,81,19), r(d1,4f,4f,9e), r(7f,dc,dc,a3),\
- r(66,22,22,44), r(7e,2a,2a,54), r(ab,90,90,3b), r(83,88,88,0b),\
- r(ca,46,46,8c), r(29,ee,ee,c7), r(d3,b8,b8,6b), r(3c,14,14,28),\
- r(79,de,de,a7), r(e2,5e,5e,bc), r(1d,0b,0b,16), r(76,db,db,ad),\
- r(3b,e0,e0,db), r(56,32,32,64), r(4e,3a,3a,74), r(1e,0a,0a,14),\
- r(db,49,49,92), r(0a,06,06,0c), r(6c,24,24,48), r(e4,5c,5c,b8),\
- r(5d,c2,c2,9f), r(6e,d3,d3,bd), r(ef,ac,ac,43), r(a6,62,62,c4),\
- r(a8,91,91,39), r(a4,95,95,31), r(37,e4,e4,d3), r(8b,79,79,f2),\
- r(32,e7,e7,d5), r(43,c8,c8,8b), r(59,37,37,6e), r(b7,6d,6d,da),\
- r(8c,8d,8d,01), r(64,d5,d5,b1), r(d2,4e,4e,9c), r(e0,a9,a9,49),\
- r(b4,6c,6c,d8), r(fa,56,56,ac), r(07,f4,f4,f3), r(25,ea,ea,cf),\
- r(af,65,65,ca), r(8e,7a,7a,f4), r(e9,ae,ae,47), r(18,08,08,10),\
- r(d5,ba,ba,6f), r(88,78,78,f0), r(6f,25,25,4a), r(72,2e,2e,5c),\
- r(24,1c,1c,38), r(f1,a6,a6,57), r(c7,b4,b4,73), r(51,c6,c6,97),\
- r(23,e8,e8,cb), r(7c,dd,dd,a1), r(9c,74,74,e8), r(21,1f,1f,3e),\
- r(dd,4b,4b,96), r(dc,bd,bd,61), r(86,8b,8b,0d), r(85,8a,8a,0f),\
- r(90,70,70,e0), r(42,3e,3e,7c), r(c4,b5,b5,71), r(aa,66,66,cc),\
- r(d8,48,48,90), r(05,03,03,06), r(01,f6,f6,f7), r(12,0e,0e,1c),\
- r(a3,61,61,c2), r(5f,35,35,6a), r(f9,57,57,ae), r(d0,b9,b9,69),\
- r(91,86,86,17), r(58,c1,c1,99), r(27,1d,1d,3a), r(b9,9e,9e,27),\
- r(38,e1,e1,d9), r(13,f8,f8,eb), r(b3,98,98,2b), r(33,11,11,22),\
- r(bb,69,69,d2), r(70,d9,d9,a9), r(89,8e,8e,07), r(a7,94,94,33),\
- r(b6,9b,9b,2d), r(22,1e,1e,3c), r(92,87,87,15), r(20,e9,e9,c9),\
- r(49,ce,ce,87), r(ff,55,55,aa), r(78,28,28,50), r(7a,df,df,a5),\
- r(8f,8c,8c,03), r(f8,a1,a1,59), r(80,89,89,09), r(17,0d,0d,1a),\
- r(da,bf,bf,65), r(31,e6,e6,d7), r(c6,42,42,84), r(b8,68,68,d0),\
- r(c3,41,41,82), r(b0,99,99,29), r(77,2d,2d,5a), r(11,0f,0f,1e),\
- r(cb,b0,b0,7b), r(fc,54,54,a8), r(d6,bb,bb,6d), r(3a,16,16,2c)
-
-// data for inverse tables (other than last round)
-
-#define i_table \
- r(50,a7,f4,51), r(53,65,41,7e), r(c3,a4,17,1a), r(96,5e,27,3a),\
- r(cb,6b,ab,3b), r(f1,45,9d,1f), r(ab,58,fa,ac), r(93,03,e3,4b),\
- r(55,fa,30,20), r(f6,6d,76,ad), r(91,76,cc,88), r(25,4c,02,f5),\
- r(fc,d7,e5,4f), r(d7,cb,2a,c5), r(80,44,35,26), r(8f,a3,62,b5),\
- r(49,5a,b1,de), r(67,1b,ba,25), r(98,0e,ea,45), r(e1,c0,fe,5d),\
- r(02,75,2f,c3), r(12,f0,4c,81), r(a3,97,46,8d), r(c6,f9,d3,6b),\
- r(e7,5f,8f,03), r(95,9c,92,15), r(eb,7a,6d,bf), r(da,59,52,95),\
- r(2d,83,be,d4), r(d3,21,74,58), r(29,69,e0,49), r(44,c8,c9,8e),\
- r(6a,89,c2,75), r(78,79,8e,f4), r(6b,3e,58,99), r(dd,71,b9,27),\
- r(b6,4f,e1,be), r(17,ad,88,f0), r(66,ac,20,c9), r(b4,3a,ce,7d),\
- r(18,4a,df,63), r(82,31,1a,e5), r(60,33,51,97), r(45,7f,53,62),\
- r(e0,77,64,b1), r(84,ae,6b,bb), r(1c,a0,81,fe), r(94,2b,08,f9),\
- r(58,68,48,70), r(19,fd,45,8f), r(87,6c,de,94), r(b7,f8,7b,52),\
- r(23,d3,73,ab), r(e2,02,4b,72), r(57,8f,1f,e3), r(2a,ab,55,66),\
- r(07,28,eb,b2), r(03,c2,b5,2f), r(9a,7b,c5,86), r(a5,08,37,d3),\
- r(f2,87,28,30), r(b2,a5,bf,23), r(ba,6a,03,02), r(5c,82,16,ed),\
- r(2b,1c,cf,8a), r(92,b4,79,a7), r(f0,f2,07,f3), r(a1,e2,69,4e),\
- r(cd,f4,da,65), r(d5,be,05,06), r(1f,62,34,d1), r(8a,fe,a6,c4),\
- r(9d,53,2e,34), r(a0,55,f3,a2), r(32,e1,8a,05), r(75,eb,f6,a4),\
- r(39,ec,83,0b), r(aa,ef,60,40), r(06,9f,71,5e), r(51,10,6e,bd),\
- r(f9,8a,21,3e), r(3d,06,dd,96), r(ae,05,3e,dd), r(46,bd,e6,4d),\
- r(b5,8d,54,91), r(05,5d,c4,71), r(6f,d4,06,04), r(ff,15,50,60),\
- r(24,fb,98,19), r(97,e9,bd,d6), r(cc,43,40,89), r(77,9e,d9,67),\
- r(bd,42,e8,b0), r(88,8b,89,07), r(38,5b,19,e7), r(db,ee,c8,79),\
- r(47,0a,7c,a1), r(e9,0f,42,7c), r(c9,1e,84,f8), r(00,00,00,00),\
- r(83,86,80,09), r(48,ed,2b,32), r(ac,70,11,1e), r(4e,72,5a,6c),\
- r(fb,ff,0e,fd), r(56,38,85,0f), r(1e,d5,ae,3d), r(27,39,2d,36),\
- r(64,d9,0f,0a), r(21,a6,5c,68), r(d1,54,5b,9b), r(3a,2e,36,24),\
- r(b1,67,0a,0c), r(0f,e7,57,93), r(d2,96,ee,b4), r(9e,91,9b,1b),\
- r(4f,c5,c0,80), r(a2,20,dc,61), r(69,4b,77,5a), r(16,1a,12,1c),\
- r(0a,ba,93,e2), r(e5,2a,a0,c0), r(43,e0,22,3c), r(1d,17,1b,12),\
- r(0b,0d,09,0e), r(ad,c7,8b,f2), r(b9,a8,b6,2d), r(c8,a9,1e,14),\
- r(85,19,f1,57), r(4c,07,75,af), r(bb,dd,99,ee), r(fd,60,7f,a3),\
- r(9f,26,01,f7), r(bc,f5,72,5c), r(c5,3b,66,44), r(34,7e,fb,5b),\
- r(76,29,43,8b), r(dc,c6,23,cb), r(68,fc,ed,b6), r(63,f1,e4,b8),\
- r(ca,dc,31,d7), r(10,85,63,42), r(40,22,97,13), r(20,11,c6,84),\
- r(7d,24,4a,85), r(f8,3d,bb,d2), r(11,32,f9,ae), r(6d,a1,29,c7),\
- r(4b,2f,9e,1d), r(f3,30,b2,dc), r(ec,52,86,0d), r(d0,e3,c1,77),\
- r(6c,16,b3,2b), r(99,b9,70,a9), r(fa,48,94,11), r(22,64,e9,47),\
- r(c4,8c,fc,a8), r(1a,3f,f0,a0), r(d8,2c,7d,56), r(ef,90,33,22),\
- r(c7,4e,49,87), r(c1,d1,38,d9), r(fe,a2,ca,8c), r(36,0b,d4,98),\
- r(cf,81,f5,a6), r(28,de,7a,a5), r(26,8e,b7,da), r(a4,bf,ad,3f),\
- r(e4,9d,3a,2c), r(0d,92,78,50), r(9b,cc,5f,6a), r(62,46,7e,54),\
- r(c2,13,8d,f6), r(e8,b8,d8,90), r(5e,f7,39,2e), r(f5,af,c3,82),\
- r(be,80,5d,9f), r(7c,93,d0,69), r(a9,2d,d5,6f), r(b3,12,25,cf),\
- r(3b,99,ac,c8), r(a7,7d,18,10), r(6e,63,9c,e8), r(7b,bb,3b,db),\
- r(09,78,26,cd), r(f4,18,59,6e), r(01,b7,9a,ec), r(a8,9a,4f,83),\
- r(65,6e,95,e6), r(7e,e6,ff,aa), r(08,cf,bc,21), r(e6,e8,15,ef),\
- r(d9,9b,e7,ba), r(ce,36,6f,4a), r(d4,09,9f,ea), r(d6,7c,b0,29),\
- r(af,b2,a4,31), r(31,23,3f,2a), r(30,94,a5,c6), r(c0,66,a2,35),\
- r(37,bc,4e,74), r(a6,ca,82,fc), r(b0,d0,90,e0), r(15,d8,a7,33),\
- r(4a,98,04,f1), r(f7,da,ec,41), r(0e,50,cd,7f), r(2f,f6,91,17),\
- r(8d,d6,4d,76), r(4d,b0,ef,43), r(54,4d,aa,cc), r(df,04,96,e4),\
- r(e3,b5,d1,9e), r(1b,88,6a,4c), r(b8,1f,2c,c1), r(7f,51,65,46),\
- r(04,ea,5e,9d), r(5d,35,8c,01), r(73,74,87,fa), r(2e,41,0b,fb),\
- r(5a,1d,67,b3), r(52,d2,db,92), r(33,56,10,e9), r(13,47,d6,6d),\
- r(8c,61,d7,9a), r(7a,0c,a1,37), r(8e,14,f8,59), r(89,3c,13,eb),\
- r(ee,27,a9,ce), r(35,c9,61,b7), r(ed,e5,1c,e1), r(3c,b1,47,7a),\
- r(59,df,d2,9c), r(3f,73,f2,55), r(79,ce,14,18), r(bf,37,c7,73),\
- r(ea,cd,f7,53), r(5b,aa,fd,5f), r(14,6f,3d,df), r(86,db,44,78),\
- r(81,f3,af,ca), r(3e,c4,68,b9), r(2c,34,24,38), r(5f,40,a3,c2),\
- r(72,c3,1d,16), r(0c,25,e2,bc), r(8b,49,3c,28), r(41,95,0d,ff),\
- r(71,01,a8,39), r(de,b3,0c,08), r(9c,e4,b4,d8), r(90,c1,56,64),\
- r(61,84,cb,7b), r(70,b6,32,d5), r(74,5c,6c,48), r(42,57,b8,d0)
-
-// generate the required tables in the desired endian format
-
-#undef r
-#define r r0
-
-#if defined(ONE_TABLE)
-static const u_int32_t ft_tab[256] =
- { f_table };
-#elif defined(FOUR_TABLES)
-static const u_int32_t ft_tab[4][256] =
-{ { f_table },
-#undef r
-#define r r1
- { f_table },
-#undef r
-#define r r2
- { f_table },
-#undef r
-#define r r3
- { f_table }
-};
-#endif
-
-#undef r
-#define r r0
-#if defined(ONE_TABLE)
-static const u_int32_t it_tab[256] =
- { i_table };
-#elif defined(FOUR_TABLES)
-static const u_int32_t it_tab[4][256] =
-{ { i_table },
-#undef r
-#define r r1
- { i_table },
-#undef r
-#define r r2
- { i_table },
-#undef r
-#define r r3
- { i_table }
-};
-#endif
-
-#endif
-
-#if defined(FIXED_TABLES) && (defined(ONE_LR_TABLE) || defined(FOUR_LR_TABLES))
-
-// data for inverse tables (last round)
-
-#define li_table \
- w(52), w(09), w(6a), w(d5), w(30), w(36), w(a5), w(38),\
- w(bf), w(40), w(a3), w(9e), w(81), w(f3), w(d7), w(fb),\
- w(7c), w(e3), w(39), w(82), w(9b), w(2f), w(ff), w(87),\
- w(34), w(8e), w(43), w(44), w(c4), w(de), w(e9), w(cb),\
- w(54), w(7b), w(94), w(32), w(a6), w(c2), w(23), w(3d),\
- w(ee), w(4c), w(95), w(0b), w(42), w(fa), w(c3), w(4e),\
- w(08), w(2e), w(a1), w(66), w(28), w(d9), w(24), w(b2),\
- w(76), w(5b), w(a2), w(49), w(6d), w(8b), w(d1), w(25),\
- w(72), w(f8), w(f6), w(64), w(86), w(68), w(98), w(16),\
- w(d4), w(a4), w(5c), w(cc), w(5d), w(65), w(b6), w(92),\
- w(6c), w(70), w(48), w(50), w(fd), w(ed), w(b9), w(da),\
- w(5e), w(15), w(46), w(57), w(a7), w(8d), w(9d), w(84),\
- w(90), w(d8), w(ab), w(00), w(8c), w(bc), w(d3), w(0a),\
- w(f7), w(e4), w(58), w(05), w(b8), w(b3), w(45), w(06),\
- w(d0), w(2c), w(1e), w(8f), w(ca), w(3f), w(0f), w(02),\
- w(c1), w(af), w(bd), w(03), w(01), w(13), w(8a), w(6b),\
- w(3a), w(91), w(11), w(41), w(4f), w(67), w(dc), w(ea),\
- w(97), w(f2), w(cf), w(ce), w(f0), w(b4), w(e6), w(73),\
- w(96), w(ac), w(74), w(22), w(e7), w(ad), w(35), w(85),\
- w(e2), w(f9), w(37), w(e8), w(1c), w(75), w(df), w(6e),\
- w(47), w(f1), w(1a), w(71), w(1d), w(29), w(c5), w(89),\
- w(6f), w(b7), w(62), w(0e), w(aa), w(18), w(be), w(1b),\
- w(fc), w(56), w(3e), w(4b), w(c6), w(d2), w(79), w(20),\
- w(9a), w(db), w(c0), w(fe), w(78), w(cd), w(5a), w(f4),\
- w(1f), w(dd), w(a8), w(33), w(88), w(07), w(c7), w(31),\
- w(b1), w(12), w(10), w(59), w(27), w(80), w(ec), w(5f),\
- w(60), w(51), w(7f), w(a9), w(19), w(b5), w(4a), w(0d),\
- w(2d), w(e5), w(7a), w(9f), w(93), w(c9), w(9c), w(ef),\
- w(a0), w(e0), w(3b), w(4d), w(ae), w(2a), w(f5), w(b0),\
- w(c8), w(eb), w(bb), w(3c), w(83), w(53), w(99), w(61),\
- w(17), w(2b), w(04), w(7e), w(ba), w(77), w(d6), w(26),\
- w(e1), w(69), w(14), w(63), w(55), w(21), w(0c), w(7d),
-
-// generate the required tables in the desired endian format
-
-#undef r
-#define r(p,q,r,s) w0(q)
-#if defined(ONE_LR_TABLE)
-static const u_int32_t fl_tab[256] =
- { f_table };
-#elif defined(FOUR_LR_TABLES)
-static const u_int32_t fl_tab[4][256] =
-{ { f_table },
-#undef r
-#define r(p,q,r,s) w1(q)
- { f_table },
-#undef r
-#define r(p,q,r,s) w2(q)
- { f_table },
-#undef r
-#define r(p,q,r,s) w3(q)
- { f_table }
-};
-#endif
-
-#undef w
-#define w w0
-#if defined(ONE_LR_TABLE)
-static const u_int32_t il_tab[256] =
- { li_table };
-#elif defined(FOUR_LR_TABLES)
-static const u_int32_t il_tab[4][256] =
-{ { li_table },
-#undef w
-#define w w1
- { li_table },
-#undef w
-#define w w2
- { li_table },
-#undef w
-#define w w3
- { li_table }
-};
-#endif
-
-#endif
-
-#if defined(FIXED_TABLES) && (defined(ONE_IM_TABLE) || defined(FOUR_IM_TABLES))
-
-#define m_table \
- r(00,00,00,00), r(0b,0d,09,0e), r(16,1a,12,1c), r(1d,17,1b,12),\
- r(2c,34,24,38), r(27,39,2d,36), r(3a,2e,36,24), r(31,23,3f,2a),\
- r(58,68,48,70), r(53,65,41,7e), r(4e,72,5a,6c), r(45,7f,53,62),\
- r(74,5c,6c,48), r(7f,51,65,46), r(62,46,7e,54), r(69,4b,77,5a),\
- r(b0,d0,90,e0), r(bb,dd,99,ee), r(a6,ca,82,fc), r(ad,c7,8b,f2),\
- r(9c,e4,b4,d8), r(97,e9,bd,d6), r(8a,fe,a6,c4), r(81,f3,af,ca),\
- r(e8,b8,d8,90), r(e3,b5,d1,9e), r(fe,a2,ca,8c), r(f5,af,c3,82),\
- r(c4,8c,fc,a8), r(cf,81,f5,a6), r(d2,96,ee,b4), r(d9,9b,e7,ba),\
- r(7b,bb,3b,db), r(70,b6,32,d5), r(6d,a1,29,c7), r(66,ac,20,c9),\
- r(57,8f,1f,e3), r(5c,82,16,ed), r(41,95,0d,ff), r(4a,98,04,f1),\
- r(23,d3,73,ab), r(28,de,7a,a5), r(35,c9,61,b7), r(3e,c4,68,b9),\
- r(0f,e7,57,93), r(04,ea,5e,9d), r(19,fd,45,8f), r(12,f0,4c,81),\
- r(cb,6b,ab,3b), r(c0,66,a2,35), r(dd,71,b9,27), r(d6,7c,b0,29),\
- r(e7,5f,8f,03), r(ec,52,86,0d), r(f1,45,9d,1f), r(fa,48,94,11),\
- r(93,03,e3,4b), r(98,0e,ea,45), r(85,19,f1,57), r(8e,14,f8,59),\
- r(bf,37,c7,73), r(b4,3a,ce,7d), r(a9,2d,d5,6f), r(a2,20,dc,61),\
- r(f6,6d,76,ad), r(fd,60,7f,a3), r(e0,77,64,b1), r(eb,7a,6d,bf),\
- r(da,59,52,95), r(d1,54,5b,9b), r(cc,43,40,89), r(c7,4e,49,87),\
- r(ae,05,3e,dd), r(a5,08,37,d3), r(b8,1f,2c,c1), r(b3,12,25,cf),\
- r(82,31,1a,e5), r(89,3c,13,eb), r(94,2b,08,f9), r(9f,26,01,f7),\
- r(46,bd,e6,4d), r(4d,b0,ef,43), r(50,a7,f4,51), r(5b,aa,fd,5f),\
- r(6a,89,c2,75), r(61,84,cb,7b), r(7c,93,d0,69), r(77,9e,d9,67),\
- r(1e,d5,ae,3d), r(15,d8,a7,33), r(08,cf,bc,21), r(03,c2,b5,2f),\
- r(32,e1,8a,05), r(39,ec,83,0b), r(24,fb,98,19), r(2f,f6,91,17),\
- r(8d,d6,4d,76), r(86,db,44,78), r(9b,cc,5f,6a), r(90,c1,56,64),\
- r(a1,e2,69,4e), r(aa,ef,60,40), r(b7,f8,7b,52), r(bc,f5,72,5c),\
- r(d5,be,05,06), r(de,b3,0c,08), r(c3,a4,17,1a), r(c8,a9,1e,14),\
- r(f9,8a,21,3e), r(f2,87,28,30), r(ef,90,33,22), r(e4,9d,3a,2c),\
- r(3d,06,dd,96), r(36,0b,d4,98), r(2b,1c,cf,8a), r(20,11,c6,84),\
- r(11,32,f9,ae), r(1a,3f,f0,a0), r(07,28,eb,b2), r(0c,25,e2,bc),\
- r(65,6e,95,e6), r(6e,63,9c,e8), r(73,74,87,fa), r(78,79,8e,f4),\
- r(49,5a,b1,de), r(42,57,b8,d0), r(5f,40,a3,c2), r(54,4d,aa,cc),\
- r(f7,da,ec,41), r(fc,d7,e5,4f), r(e1,c0,fe,5d), r(ea,cd,f7,53),\
- r(db,ee,c8,79), r(d0,e3,c1,77), r(cd,f4,da,65), r(c6,f9,d3,6b),\
- r(af,b2,a4,31), r(a4,bf,ad,3f), r(b9,a8,b6,2d), r(b2,a5,bf,23),\
- r(83,86,80,09), r(88,8b,89,07), r(95,9c,92,15), r(9e,91,9b,1b),\
- r(47,0a,7c,a1), r(4c,07,75,af), r(51,10,6e,bd), r(5a,1d,67,b3),\
- r(6b,3e,58,99), r(60,33,51,97), r(7d,24,4a,85), r(76,29,43,8b),\
- r(1f,62,34,d1), r(14,6f,3d,df), r(09,78,26,cd), r(02,75,2f,c3),\
- r(33,56,10,e9), r(38,5b,19,e7), r(25,4c,02,f5), r(2e,41,0b,fb),\
- r(8c,61,d7,9a), r(87,6c,de,94), r(9a,7b,c5,86), r(91,76,cc,88),\
- r(a0,55,f3,a2), r(ab,58,fa,ac), r(b6,4f,e1,be), r(bd,42,e8,b0),\
- r(d4,09,9f,ea), r(df,04,96,e4), r(c2,13,8d,f6), r(c9,1e,84,f8),\
- r(f8,3d,bb,d2), r(f3,30,b2,dc), r(ee,27,a9,ce), r(e5,2a,a0,c0),\
- r(3c,b1,47,7a), r(37,bc,4e,74), r(2a,ab,55,66), r(21,a6,5c,68),\
- r(10,85,63,42), r(1b,88,6a,4c), r(06,9f,71,5e), r(0d,92,78,50),\
- r(64,d9,0f,0a), r(6f,d4,06,04), r(72,c3,1d,16), r(79,ce,14,18),\
- r(48,ed,2b,32), r(43,e0,22,3c), r(5e,f7,39,2e), r(55,fa,30,20),\
- r(01,b7,9a,ec), r(0a,ba,93,e2), r(17,ad,88,f0), r(1c,a0,81,fe),\
- r(2d,83,be,d4), r(26,8e,b7,da), r(3b,99,ac,c8), r(30,94,a5,c6),\
- r(59,df,d2,9c), r(52,d2,db,92), r(4f,c5,c0,80), r(44,c8,c9,8e),\
- r(75,eb,f6,a4), r(7e,e6,ff,aa), r(63,f1,e4,b8), r(68,fc,ed,b6),\
- r(b1,67,0a,0c), r(ba,6a,03,02), r(a7,7d,18,10), r(ac,70,11,1e),\
- r(9d,53,2e,34), r(96,5e,27,3a), r(8b,49,3c,28), r(80,44,35,26),\
- r(e9,0f,42,7c), r(e2,02,4b,72), r(ff,15,50,60), r(f4,18,59,6e),\
- r(c5,3b,66,44), r(ce,36,6f,4a), r(d3,21,74,58), r(d8,2c,7d,56),\
- r(7a,0c,a1,37), r(71,01,a8,39), r(6c,16,b3,2b), r(67,1b,ba,25),\
- r(56,38,85,0f), r(5d,35,8c,01), r(40,22,97,13), r(4b,2f,9e,1d),\
- r(22,64,e9,47), r(29,69,e0,49), r(34,7e,fb,5b), r(3f,73,f2,55),\
- r(0e,50,cd,7f), r(05,5d,c4,71), r(18,4a,df,63), r(13,47,d6,6d),\
- r(ca,dc,31,d7), r(c1,d1,38,d9), r(dc,c6,23,cb), r(d7,cb,2a,c5),\
- r(e6,e8,15,ef), r(ed,e5,1c,e1), r(f0,f2,07,f3), r(fb,ff,0e,fd),\
- r(92,b4,79,a7), r(99,b9,70,a9), r(84,ae,6b,bb), r(8f,a3,62,b5),\
- r(be,80,5d,9f), r(b5,8d,54,91), r(a8,9a,4f,83), r(a3,97,46,8d)
-
-#undef r
-#define r r0
-
-#if defined(ONE_IM_TABLE)
-static const u_int32_t im_tab[256] =
- { m_table };
-#elif defined(FOUR_IM_TABLES)
-static const u_int32_t im_tab[4][256] =
-{ { m_table },
-#undef r
-#define r r1
- { m_table },
-#undef r
-#define r r2
- { m_table },
-#undef r
-#define r r3
- { m_table }
-};
-#endif
-
-#endif
-
-#else
-
-static int tab_gen = 0;
-
-static unsigned char s_box[256]; // the S box
-static unsigned char inv_s_box[256]; // the inverse S box
-static u_int32_t rcon_tab[AES_RC_LENGTH]; // table of round constants
-
-#if defined(ONE_TABLE)
-static u_int32_t ft_tab[256];
-static u_int32_t it_tab[256];
-#elif defined(FOUR_TABLES)
-static u_int32_t ft_tab[4][256];
-static u_int32_t it_tab[4][256];
-#endif
-
-#if defined(ONE_LR_TABLE)
-static u_int32_t fl_tab[256];
-static u_int32_t il_tab[256];
-#elif defined(FOUR_LR_TABLES)
-static u_int32_t fl_tab[4][256];
-static u_int32_t il_tab[4][256];
-#endif
-
-#if defined(ONE_IM_TABLE)
-static u_int32_t im_tab[256];
-#elif defined(FOUR_IM_TABLES)
-static u_int32_t im_tab[4][256];
-#endif
-
-// Generate the tables for the dynamic table option
-
-#if !defined(FF_TABLES)
-
-// It will generally be sensible to use tables to compute finite
-// field multiplies and inverses but where memory is scarse this
-// code might sometimes be better.
-
-// return 2 ^ (n - 1) where n is the bit number of the highest bit
-// set in x with x in the range 1 < x < 0x00000200. This form is
-// used so that locals within FFinv can be bytes rather than words
-
-static unsigned char hibit(const u_int32_t x)
-{ unsigned char r = (unsigned char)((x >> 1) | (x >> 2));
-
- r |= (r >> 2);
- r |= (r >> 4);
- return (r + 1) >> 1;
-}
-
-// return the inverse of the finite field element x
-
-static unsigned char FFinv(const unsigned char x)
-{ unsigned char p1 = x, p2 = 0x1b, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
-
- if(x < 2) return x;
-
- for(;;)
- {
- if(!n1) return v1;
-
- while(n2 >= n1)
- {
- n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
- }
-
- if(!n2) return v2;
-
- while(n1 >= n2)
- {
- n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
- }
- }
-}
-
-// define the finite field multiplies required for Rijndael
-
-#define FFmul02(x) ((((x) & 0x7f) << 1) ^ ((x) & 0x80 ? 0x1b : 0))
-#define FFmul03(x) ((x) ^ FFmul02(x))
-#define FFmul09(x) ((x) ^ FFmul02(FFmul02(FFmul02(x))))
-#define FFmul0b(x) ((x) ^ FFmul02((x) ^ FFmul02(FFmul02(x))))
-#define FFmul0d(x) ((x) ^ FFmul02(FFmul02((x) ^ FFmul02(x))))
-#define FFmul0e(x) FFmul02((x) ^ FFmul02((x) ^ FFmul02(x)))
-
-#else
-
-#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
-
-#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
-#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
-#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
-#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
-#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
-#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
-
-#endif
-
-// The forward and inverse affine transformations used in the S-box
-
-#define fwd_affine(x) \
- (w = (u_int32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(unsigned char)(w^(w>>8)))
-
-#define inv_affine(x) \
- (w = (u_int32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(unsigned char)(w^(w>>8)))
-
-static void gen_tabs(void)
-{ u_int32_t i, w;
-
-#if defined(FF_TABLES)
-
- unsigned char pow[512], log[256];
-
- // log and power tables for GF(2^8) finite field with
- // 0x011b as modular polynomial - the simplest primitive
- // root is 0x03, used here to generate the tables
-
- i = 0; w = 1;
- do
- {
- pow[i] = (unsigned char)w;
- pow[i + 255] = (unsigned char)w;
- log[w] = (unsigned char)i++;
- w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
- }
- while (w != 1);
-
-#endif
-
- for(i = 0, w = 1; i < AES_RC_LENGTH; ++i)
- {
- rcon_tab[i] = bytes2word(w, 0, 0, 0);
- w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
- }
-
- for(i = 0; i < 256; ++i)
- { unsigned char b;
-
- s_box[i] = b = fwd_affine(FFinv((unsigned char)i));
-
- w = bytes2word(b, 0, 0, 0);
-#if defined(ONE_LR_TABLE)
- fl_tab[i] = w;
-#elif defined(FOUR_LR_TABLES)
- fl_tab[0][i] = w;
- fl_tab[1][i] = upr(w,1);
- fl_tab[2][i] = upr(w,2);
- fl_tab[3][i] = upr(w,3);
-#endif
- w = bytes2word(FFmul02(b), b, b, FFmul03(b));
-#if defined(ONE_TABLE)
- ft_tab[i] = w;
-#elif defined(FOUR_TABLES)
- ft_tab[0][i] = w;
- ft_tab[1][i] = upr(w,1);
- ft_tab[2][i] = upr(w,2);
- ft_tab[3][i] = upr(w,3);
-#endif
- inv_s_box[i] = b = FFinv(inv_affine((unsigned char)i));
-
- w = bytes2word(b, 0, 0, 0);
-#if defined(ONE_LR_TABLE)
- il_tab[i] = w;
-#elif defined(FOUR_LR_TABLES)
- il_tab[0][i] = w;
- il_tab[1][i] = upr(w,1);
- il_tab[2][i] = upr(w,2);
- il_tab[3][i] = upr(w,3);
-#endif
- w = bytes2word(FFmul0e(b), FFmul09(b), FFmul0d(b), FFmul0b(b));
-#if defined(ONE_TABLE)
- it_tab[i] = w;
-#elif defined(FOUR_TABLES)
- it_tab[0][i] = w;
- it_tab[1][i] = upr(w,1);
- it_tab[2][i] = upr(w,2);
- it_tab[3][i] = upr(w,3);
-#endif
-#if defined(ONE_IM_TABLE)
- im_tab[b] = w;
-#elif defined(FOUR_IM_TABLES)
- im_tab[0][b] = w;
- im_tab[1][b] = upr(w,1);
- im_tab[2][b] = upr(w,2);
- im_tab[3][b] = upr(w,3);
-#endif
-
- }
-}
-
-#endif
-
-#define no_table(x,box,vf,rf,c) bytes2word( \
- box[bval(vf(x,0,c),rf(0,c))], \
- box[bval(vf(x,1,c),rf(1,c))], \
- box[bval(vf(x,2,c),rf(2,c))], \
- box[bval(vf(x,3,c),rf(3,c))])
-
-#define one_table(x,op,tab,vf,rf,c) \
- ( tab[bval(vf(x,0,c),rf(0,c))] \
- ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \
- ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \
- ^ op(tab[bval(vf(x,3,c),rf(3,c))],3))
-
-#define four_tables(x,tab,vf,rf,c) \
- ( tab[0][bval(vf(x,0,c),rf(0,c))] \
- ^ tab[1][bval(vf(x,1,c),rf(1,c))] \
- ^ tab[2][bval(vf(x,2,c),rf(2,c))] \
- ^ tab[3][bval(vf(x,3,c),rf(3,c))])
-
-#define vf1(x,r,c) (x)
-#define rf1(r,c) (r)
-#define rf2(r,c) ((r-c)&3)
-
-#if defined(FOUR_LR_TABLES)
-#define ls_box(x,c) four_tables(x,fl_tab,vf1,rf2,c)
-#elif defined(ONE_LR_TABLE)
-#define ls_box(x,c) one_table(x,upr,fl_tab,vf1,rf2,c)
-#else
-#define ls_box(x,c) no_table(x,s_box,vf1,rf2,c)
-#endif
-
-#if defined(FOUR_IM_TABLES)
-#define inv_mcol(x) four_tables(x,im_tab,vf1,rf1,0)
-#elif defined(ONE_IM_TABLE)
-#define inv_mcol(x) one_table(x,upr,im_tab,vf1,rf1,0)
-#else
-#define inv_mcol(x) \
- (f9 = (x),f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
- f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
-#endif
-
-#define nc (AES_BLOCK_SIZE/4)
-
-// Initialise the key schedule from the user supplied key. The key
-// length is now specified in bytes - 16, 24 or 32 as appropriate.
-// This corresponds to bit lengths of 128, 192 and 256 bits, and
-// to Nk values of 4, 6 and 8 respectively.
-
-#define mx(t,f) (*t++ = inv_mcol(*f),f++)
-#define cp(t,f) *t++ = *f++
-
-#if AES_BLOCK_SIZE == 16
-#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-#elif AES_BLOCK_SIZE == 24
-#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
- cp(d,s); cp(d,s)
-#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
- mx(d,s); mx(d,s)
-#elif AES_BLOCK_SIZE == 32
-#define cpy(d,s) cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
- cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-#define mix(d,s) mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
- mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-#else
-
-#define cpy(d,s) \
-switch(nc) \
-{ case 8: cp(d,s); cp(d,s); \
- case 6: cp(d,s); cp(d,s); \
- case 4: cp(d,s); cp(d,s); \
- cp(d,s); cp(d,s); \
-}
-
-#define mix(d,s) \
-switch(nc) \
-{ case 8: mx(d,s); mx(d,s); \
- case 6: mx(d,s); mx(d,s); \
- case 4: mx(d,s); mx(d,s); \
- mx(d,s); mx(d,s); \
-}
-
-#endif
-
-// y = output word, x = input word, r = row, c = column
-// for r = 0, 1, 2 and 3 = column accessed for row r
-
-#if defined(ARRAYS)
-#define s(x,c) x[c]
-#else
-#define s(x,c) x##c
-#endif
-
-// I am grateful to Frank Yellin for the following constructions
-// which, given the column (c) of the output state variable that
-// is being computed, return the input state variables which are
-// needed for each row (r) of the state
-
-// For the fixed block size options, compilers reduce these two
-// expressions to fixed variable references. For variable block
-// size code conditional clauses will sometimes be returned
-
-#define unused 77 // Sunset Strip
-
-#define fwd_var(x,r,c) \
- ( r==0 ? \
- ( c==0 ? s(x,0) \
- : c==1 ? s(x,1) \
- : c==2 ? s(x,2) \
- : c==3 ? s(x,3) \
- : c==4 ? s(x,4) \
- : c==5 ? s(x,5) \
- : c==6 ? s(x,6) \
- : s(x,7)) \
- : r==1 ? \
- ( c==0 ? s(x,1) \
- : c==1 ? s(x,2) \
- : c==2 ? s(x,3) \
- : c==3 ? nc==4 ? s(x,0) : s(x,4) \
- : c==4 ? s(x,5) \
- : c==5 ? nc==8 ? s(x,6) : s(x,0) \
- : c==6 ? s(x,7) \
- : s(x,0)) \
- : r==2 ? \
- ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
- : c==1 ? nc==8 ? s(x,4) : s(x,3) \
- : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
- : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
- : c==4 ? nc==8 ? s(x,7) : s(x,0) \
- : c==5 ? nc==8 ? s(x,0) : s(x,1) \
- : c==6 ? s(x,1) \
- : s(x,2)) \
- : \
- ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
- : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
- : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
- : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
- : c==4 ? nc==8 ? s(x,0) : s(x,1) \
- : c==5 ? nc==8 ? s(x,1) : s(x,2) \
- : c==6 ? s(x,2) \
- : s(x,3)))
-
-#define inv_var(x,r,c) \
- ( r==0 ? \
- ( c==0 ? s(x,0) \
- : c==1 ? s(x,1) \
- : c==2 ? s(x,2) \
- : c==3 ? s(x,3) \
- : c==4 ? s(x,4) \
- : c==5 ? s(x,5) \
- : c==6 ? s(x,6) \
- : s(x,7)) \
- : r==1 ? \
- ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
- : c==1 ? s(x,0) \
- : c==2 ? s(x,1) \
- : c==3 ? s(x,2) \
- : c==4 ? s(x,3) \
- : c==5 ? s(x,4) \
- : c==6 ? s(x,5) \
- : s(x,6)) \
- : r==2 ? \
- ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
- : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
- : c==2 ? nc==8 ? s(x,7) : s(x,0) \
- : c==3 ? nc==8 ? s(x,0) : s(x,1) \
- : c==4 ? nc==8 ? s(x,1) : s(x,2) \
- : c==5 ? nc==8 ? s(x,2) : s(x,3) \
- : c==6 ? s(x,3) \
- : s(x,4)) \
- : \
- ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
- : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
- : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
- : c==3 ? nc==8 ? s(x,7) : s(x,0) \
- : c==4 ? nc==8 ? s(x,0) : s(x,1) \
- : c==5 ? nc==8 ? s(x,1) : s(x,2) \
- : c==6 ? s(x,2) \
- : s(x,3)))
-
-#define si(y,x,k,c) s(y,c) = const_word_in(x + 4 * c) ^ k[c]
-#define so(y,x,c) word_out(y + 4 * c, s(x,c))
-
-#if defined(FOUR_TABLES)
-#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
-#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
-#elif defined(ONE_TABLE)
-#define fwd_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
-#define inv_rnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
-#else
-#define fwd_rnd(y,x,k,c) s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
-#define inv_rnd(y,x,k,c) s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
-#endif
-
-#if defined(FOUR_LR_TABLES)
-#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
-#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
-#elif defined(ONE_LR_TABLE)
-#define fwd_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
-#define inv_lrnd(y,x,k,c) s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
-#else
-#define fwd_lrnd(y,x,k,c) s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
-#define inv_lrnd(y,x,k,c) s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
-#endif
-
-#if AES_BLOCK_SIZE == 16
-
-#if defined(ARRAYS)
-#define locals(y,x) x[4],y[4]
-#else
-#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
-// the following defines prevent the compiler requiring the declaration
-// of generated but unused variables in the fwd_var and inv_var macros
-#define b04 unused
-#define b05 unused
-#define b06 unused
-#define b07 unused
-#define b14 unused
-#define b15 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
- s(y,2) = s(x,2); s(y,3) = s(x,3);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
-#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
-
-#elif AES_BLOCK_SIZE == 24
-
-#if defined(ARRAYS)
-#define locals(y,x) x[6],y[6]
-#else
-#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5, \
- y##0,y##1,y##2,y##3,y##4,y##5
-#define b06 unused
-#define b07 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
- s(y,2) = s(x,2); s(y,3) = s(x,3); \
- s(y,4) = s(x,4); s(y,5) = s(x,5);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
- si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
-#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); \
- so(y,x,3); so(y,x,4); so(y,x,5)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
- rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
-#else
-
-#if defined(ARRAYS)
-#define locals(y,x) x[8],y[8]
-#else
-#define locals(y,x) x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
- y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
-#endif
-#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \
- s(y,2) = s(x,2); s(y,3) = s(x,3); \
- s(y,4) = s(x,4); s(y,5) = s(x,5); \
- s(y,6) = s(x,6); s(y,7) = s(x,7);
-
-#if AES_BLOCK_SIZE == 32
-
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
- si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
-#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
- so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
- rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
-#else
-
-#define state_in(y,x,k) \
-switch(nc) \
-{ case 8: si(y,x,k,7); si(y,x,k,6); \
- case 6: si(y,x,k,5); si(y,x,k,4); \
- case 4: si(y,x,k,3); si(y,x,k,2); \
- si(y,x,k,1); si(y,x,k,0); \
-}
-
-#define state_out(y,x) \
-switch(nc) \
-{ case 8: so(y,x,7); so(y,x,6); \
- case 6: so(y,x,5); so(y,x,4); \
- case 4: so(y,x,3); so(y,x,2); \
- so(y,x,1); so(y,x,0); \
-}
-
-#if defined(FAST_VARIABLE)
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
- rm(y,x,k,5); rm(y,x,k,4); \
- rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
- break; \
- case 6: rm(y,x,k,5); rm(y,x,k,4); \
- rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
- break; \
- case 4: rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
- break; \
-}
-#else
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{ case 8: rm(y,x,k,7); rm(y,x,k,6); \
- case 6: rm(y,x,k,5); rm(y,x,k,4); \
- case 4: rm(y,x,k,3); rm(y,x,k,2); \
- rm(y,x,k,1); rm(y,x,k,0); \
-}
-
-#endif
-
-#endif
-#endif
-
-/**
- * Implementation of private_aes_cbc_crypter_t.encrypt_block.
- */
-static void encrypt_block(const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
-{ u_int32_t locals(b0, b1);
- const u_int32_t *kp = this->aes_e_key;
-
-#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
- u_int32_t f2;
-#endif
-
- state_in(b0, in_blk, kp); kp += nc;
-
-#if defined(UNROLL)
-
- switch(this->aes_Nrnd)
- {
- case 14: round(fwd_rnd, b1, b0, kp );
- round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
- case 12: round(fwd_rnd, b1, b0, kp );
- round(fwd_rnd, b0, b1, kp + nc ); kp += 2 * nc;
- case 10: round(fwd_rnd, b1, b0, kp );
- round(fwd_rnd, b0, b1, kp + nc);
- round(fwd_rnd, b1, b0, kp + 2 * nc);
- round(fwd_rnd, b0, b1, kp + 3 * nc);
- round(fwd_rnd, b1, b0, kp + 4 * nc);
- round(fwd_rnd, b0, b1, kp + 5 * nc);
- round(fwd_rnd, b1, b0, kp + 6 * nc);
- round(fwd_rnd, b0, b1, kp + 7 * nc);
- round(fwd_rnd, b1, b0, kp + 8 * nc);
- round(fwd_lrnd, b0, b1, kp + 9 * nc);
- }
-
-#elif defined(PARTIAL_UNROLL)
- { u_int32_t rnd;
-
- for(rnd = 0; rnd < (this->aes_Nrnd >> 1) - 1; ++rnd)
- {
- round(fwd_rnd, b1, b0, kp);
- round(fwd_rnd, b0, b1, kp + nc); kp += 2 * nc;
- }
-
- round(fwd_rnd, b1, b0, kp);
- round(fwd_lrnd, b0, b1, kp + nc);
- }
-#else
- { u_int32_t rnd;
-
- for(rnd = 0; rnd < this->aes_Nrnd - 1; ++rnd)
- {
- round(fwd_rnd, b1, b0, kp);
- l_copy(b0, b1); kp += nc;
- }
-
- round(fwd_lrnd, b0, b1, kp);
- }
-#endif
-
- state_out(out_blk, b0);
-}
-
-/**
- * Implementation of private_aes_cbc_crypter_t.decrypt_block.
- */
-static void decrypt_block(const private_aes_cbc_crypter_t *this, const unsigned char in_blk[], unsigned char out_blk[])
-{ u_int32_t locals(b0, b1);
- const u_int32_t *kp = this->aes_d_key;
-
-#if !defined(ONE_TABLE) && !defined(FOUR_TABLES)
- u_int32_t f2, f4, f8, f9;
-#endif
-
- state_in(b0, in_blk, kp); kp += nc;
-
-#if defined(UNROLL)
-
- switch(this->aes_Nrnd)
- {
- case 14: round(inv_rnd, b1, b0, kp );
- round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
- case 12: round(inv_rnd, b1, b0, kp );
- round(inv_rnd, b0, b1, kp + nc ); kp += 2 * nc;
- case 10: round(inv_rnd, b1, b0, kp );
- round(inv_rnd, b0, b1, kp + nc);
- round(inv_rnd, b1, b0, kp + 2 * nc);
- round(inv_rnd, b0, b1, kp + 3 * nc);
- round(inv_rnd, b1, b0, kp + 4 * nc);
- round(inv_rnd, b0, b1, kp + 5 * nc);
- round(inv_rnd, b1, b0, kp + 6 * nc);
- round(inv_rnd, b0, b1, kp + 7 * nc);
- round(inv_rnd, b1, b0, kp + 8 * nc);
- round(inv_lrnd, b0, b1, kp + 9 * nc);
- }
-
-#elif defined(PARTIAL_UNROLL)
- { u_int32_t rnd;
-
- for(rnd = 0; rnd < (this->aes_Nrnd >> 1) - 1; ++rnd)
- {
- round(inv_rnd, b1, b0, kp);
- round(inv_rnd, b0, b1, kp + nc); kp += 2 * nc;
- }
-
- round(inv_rnd, b1, b0, kp);
- round(inv_lrnd, b0, b1, kp + nc);
- }
-#else
- { u_int32_t rnd;
-
- for(rnd = 0; rnd < this->aes_Nrnd - 1; ++rnd)
- {
- round(inv_rnd, b1, b0, kp);
- l_copy(b0, b1); kp += nc;
- }
-
- round(inv_lrnd, b0, b1, kp);
- }
-#endif
-
- state_out(out_blk, b0);
-}
-
-/**
- * Implementation of crypter_t.decrypt.
- */
-static status_t decrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
-{
- int ret, pos;
- const u_int32_t *iv_i;
- u_int8_t *in, *out;
-
- ret = data.len;
- if (((data.len) % 16) != 0)
- {
- /* data length must be padded to a multiple of blocksize */
- return INVALID_ARG;
- }
-
- decrypted->ptr = malloc(data.len);
- if (decrypted->ptr == NULL)
- {
- return OUT_OF_RES;
- }
- decrypted->len = data.len;
-
- in = data.ptr;
- out = decrypted->ptr;
-
- pos=data.len-16;
- in+=pos;
- out+=pos;
- while(pos>=0) {
- this->decrypt_block(this,in,out);
- if (pos==0)
- iv_i=(const u_int32_t*) (iv.ptr);
- else
- iv_i=(const u_int32_t*) (in-16);
- *((u_int32_t *)(&out[ 0])) ^= iv_i[0];
- *((u_int32_t *)(&out[ 4])) ^= iv_i[1];
- *((u_int32_t *)(&out[ 8])) ^= iv_i[2];
- *((u_int32_t *)(&out[12])) ^= iv_i[3];
- in-=16;
- out-=16;
- pos-=16;
- }
-
- return SUCCESS;
-}
-
-
-/**
- * Implementation of crypter_t.decrypt.
- */
-static status_t encrypt (private_aes_cbc_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
-{
- int ret, pos;
- const u_int32_t *iv_i;
- u_int8_t *in, *out;
-
- ret = data.len;
- if (((data.len) % 16) != 0)
- {
- /* data length must be padded to a multiple of blocksize */
- return INVALID_ARG;
- }
-
- encrypted->ptr = malloc(data.len);
- if (encrypted->ptr == NULL)
- {
- return OUT_OF_RES;
- }
- encrypted->len = data.len;
-
- in = data.ptr;
- out = encrypted->ptr;
-
- pos=0;
- while(pos<data.len)
- {
- if (pos==0)
- iv_i=(const u_int32_t*) iv.ptr;
- else
- iv_i=(const u_int32_t*) (out-16);
- *((u_int32_t *)(&out[ 0])) = iv_i[0]^*((const u_int32_t *)(&in[ 0]));
- *((u_int32_t *)(&out[ 4])) = iv_i[1]^*((const u_int32_t *)(&in[ 4]));
- *((u_int32_t *)(&out[ 8])) = iv_i[2]^*((const u_int32_t *)(&in[ 8]));
- *((u_int32_t *)(&out[12])) = iv_i[3]^*((const u_int32_t *)(&in[12]));
- this->encrypt_block(this,out,out);
- in+=16;
- out+=16;
- pos+=16;
- }
- return SUCCESS;
-}
-
-/**
- * Implementation of crypter_t.get_block_size.
- */
-static size_t get_block_size (private_aes_cbc_crypter_t *this)
-{
- return AES_BLOCK_SIZE;
-}
-
-/**
- * Implementation of crypter_t.get_key_size.
- */
-static size_t get_key_size (private_aes_cbc_crypter_t *this)
-{
- return this->key_size;
-}
-
-/**
- * Implementation of crypter_t.set_key.
- */
-static status_t set_key (private_aes_cbc_crypter_t *this, chunk_t key)
-{
- u_int32_t *kf, *kt, rci, f = 0;
- u_int8_t *in_key = key.ptr;
-
- if (key.len != this->key_size)
- {
- return INVALID_ARG;
- }
-
- this->aes_Nrnd = (this->aes_Nkey > (nc) ? this->aes_Nkey : (nc)) + 6;
-
- this->aes_e_key[0] = const_word_in(in_key );
- this->aes_e_key[1] = const_word_in(in_key + 4);
- this->aes_e_key[2] = const_word_in(in_key + 8);
- this->aes_e_key[3] = const_word_in(in_key + 12);
-
- kf = this->aes_e_key;
- kt = kf + nc * (this->aes_Nrnd + 1) - this->aes_Nkey;
- rci = 0;
-
- switch(this->aes_Nkey)
- {
- case 4: do
- { kf[4] = kf[0] ^ ls_box(kf[3],3) ^ rcon_tab[rci++];
- kf[5] = kf[1] ^ kf[4];
- kf[6] = kf[2] ^ kf[5];
- kf[7] = kf[3] ^ kf[6];
- kf += 4;
- }
- while(kf < kt);
- break;
-
- case 6: this->aes_e_key[4] = const_word_in(in_key + 16);
- this->aes_e_key[5] = const_word_in(in_key + 20);
- do
- { kf[ 6] = kf[0] ^ ls_box(kf[5],3) ^ rcon_tab[rci++];
- kf[ 7] = kf[1] ^ kf[ 6];
- kf[ 8] = kf[2] ^ kf[ 7];
- kf[ 9] = kf[3] ^ kf[ 8];
- kf[10] = kf[4] ^ kf[ 9];
- kf[11] = kf[5] ^ kf[10];
- kf += 6;
- }
- while(kf < kt);
- break;
-
- case 8: this->aes_e_key[4] = const_word_in(in_key + 16);
- this->aes_e_key[5] = const_word_in(in_key + 20);
- this->aes_e_key[6] = const_word_in(in_key + 24);
- this->aes_e_key[7] = const_word_in(in_key + 28);
- do
- { kf[ 8] = kf[0] ^ ls_box(kf[7],3) ^ rcon_tab[rci++];
- kf[ 9] = kf[1] ^ kf[ 8];
- kf[10] = kf[2] ^ kf[ 9];
- kf[11] = kf[3] ^ kf[10];
- kf[12] = kf[4] ^ ls_box(kf[11],0);
- kf[13] = kf[5] ^ kf[12];
- kf[14] = kf[6] ^ kf[13];
- kf[15] = kf[7] ^ kf[14];
- kf += 8;
- }
- while (kf < kt);
- break;
- }
-
- if(!f)
- {
- u_int32_t i;
-
- kt = this->aes_d_key + nc * this->aes_Nrnd;
- kf = this->aes_e_key;
-
- cpy(kt, kf); kt -= 2 * nc;
-
- for(i = 1; i < this->aes_Nrnd; ++i)
- {
-#if defined(ONE_TABLE) || defined(FOUR_TABLES)
-#if !defined(ONE_IM_TABLE) && !defined(FOUR_IM_TABLES)
- u_int32_t f2, f4, f8, f9;
-#endif
- mix(kt, kf);
-#else
- cpy(kt, kf);
-#endif
- kt -= 2 * nc;
- }
- cpy(kt, kf);
- }
-
- return SUCCESS;
-}
-
-/**
- * Implementation of crypter_t.destroy and aes_cbc_crypter_t.destroy.
- */
-static void destroy (private_aes_cbc_crypter_t *this)
-{
- free(this);
-}
-
-/*
- * Described in header
- */
-aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size)
-{
- private_aes_cbc_crypter_t *this = malloc_thing(private_aes_cbc_crypter_t);
-
- #if !defined(FIXED_TABLES)
- if(!tab_gen) { gen_tabs(); tab_gen = 1; }
- #endif
-
- this->key_size = key_size;
- switch(key_size) {
- case 32: /* bytes */
- this->aes_Nkey = 8;
- break;
- case 24: /* bytes */
- this->aes_Nkey = 6;
- break;
- case 16: /* bytes */
- this->aes_Nkey = 4;
- break;
- default:
- free(this);
- return NULL;
- }
-
- /* functions of crypter_t interface */
- this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
- this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
- this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
- this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
- this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key;
- this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
-
- /* private functions */
- this->decrypt_block = decrypt_block;
- this->encrypt_block = encrypt_block;
-
- return &(this->public);
-}
diff --git a/src/libstrongswan/crypto/crypters/aes_cbc_crypter.h b/src/libstrongswan/crypto/crypters/aes_cbc_crypter.h
deleted file mode 100644
index 5da248b8c..000000000
--- a/src/libstrongswan/crypto/crypters/aes_cbc_crypter.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file aes_cbc_crypter.h
- *
- * @brief Interface of aes_cbc_crypter_t
- *
- */
-
-/*
- * Copyright (C) 2001 Dr B. R. Gladman <brg@gladman.uk.net>
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef AES_CBC_CRYPTER_H_
-#define AES_CBC_CRYPTER_H_
-
-typedef struct aes_cbc_crypter_t aes_cbc_crypter_t;
-
-#include <crypto/crypters/crypter.h>
-
-/**
- * @brief Class implementing the AES symmetric encryption algorithm.
- *
- * @b Constructors:
- * - aes_cbc_crypter_create()
- *
- * @ingroup crypters
- */
-struct aes_cbc_crypter_t {
-
- /**
- * The crypter_t interface.
- */
- crypter_t crypter_interface;
-};
-
-/**
- * @brief Constructor to create aes_cbc_crypter_t objects.
- *
- * Supported key sizes are: 16, 24 or 32.
- *
- * @param key_size key size in bytes
- * @return
- * - aes_cbc_crypter_t object
- * - NULL if key size not supported
- */
-aes_cbc_crypter_t *aes_cbc_crypter_create(size_t key_size);
-
-
-#endif /* AES_CBC_CRYPTER_H_ */
diff --git a/src/libstrongswan/crypto/crypters/crypter.c b/src/libstrongswan/crypto/crypters/crypter.c
index 7f62741a7..2c291a9f5 100644
--- a/src/libstrongswan/crypto/crypters/crypter.c
+++ b/src/libstrongswan/crypto/crypters/crypter.c
@@ -1,10 +1,3 @@
-/**
- * @file crypter.c
- *
- * @brief Generic constructor for crypter_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,15 +12,12 @@
* 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.
+ *
+ * $Id: crypter.c 3971 2008-05-16 13:27:21Z tobias $
*/
-
#include "crypter.h"
-#include <crypto/crypters/aes_cbc_crypter.h>
-#include <crypto/crypters/des_crypter.h>
-
-
ENUM_BEGIN(encryption_algorithm_names, ENCR_UNDEFINED, ENCR_UNDEFINED,
"UNDEFINED");
ENUM_NEXT(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32, ENCR_UNDEFINED,
@@ -40,29 +30,16 @@ ENUM_NEXT(encryption_algorithm_names, ENCR_DES_IV64, ENCR_DES_IV32, ENCR_UNDEFIN
"BLOWFISH",
"3IDEA",
"DES_IV32");
-ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CTR, ENCR_DES_IV32,
+ENUM_NEXT(encryption_algorithm_names, ENCR_NULL, ENCR_AES_CCM_ICV16, ENCR_DES_IV32,
"NULL",
"AES_CBC",
- "AES_CTR");
-ENUM_END(encryption_algorithm_names, ENCR_AES_CTR);
+ "AES_CTR",
+ "AES_CCM_8",
+ "AES_CCM_12",
+ "AES_CCM_16");
+ENUM_NEXT(encryption_algorithm_names, ENCR_AES_GCM_ICV8, ENCR_AES_GCM_ICV16, ENCR_AES_CCM_ICV16,
+ "AES_GCM_8",
+ "AES_GCM_12",
+ "AES_GCM_16");
+ENUM_END(encryption_algorithm_names, ENCR_AES_GCM_ICV16);
-/*
- * Described in header.
- */
-crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size)
-{
- switch (encryption_algorithm)
- {
- case ENCR_AES_CBC:
- {
- return (crypter_t*)aes_cbc_crypter_create(key_size);
- }
- case ENCR_DES:
- case ENCR_3DES:
- {
- return (crypter_t*)des_crypter_create(encryption_algorithm);
- }
- default:
- return NULL;
- }
-}
diff --git a/src/libstrongswan/crypto/crypters/crypter.h b/src/libstrongswan/crypto/crypters/crypter.h
index 46d94ce93..aade888fa 100644
--- a/src/libstrongswan/crypto/crypters/crypter.h
+++ b/src/libstrongswan/crypto/crypters/crypter.h
@@ -1,10 +1,3 @@
-/**
- * @file crypter.h
- *
- * @brief Interface crypter_t
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* 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.
+ *
+ * $Id: crypter.h 3971 2008-05-16 13:27:21Z tobias $
+ */
+
+/**
+ * @defgroup crypter crypter
+ * @{ @ingroup crypto
*/
#ifndef CRYPTER_H_
@@ -30,21 +30,12 @@ typedef struct crypter_t crypter_t;
#include <library.h>
/**
- * @brief Encryption algorithm, as in IKEv2 RFC 3.3.2.
- *
- * Currently only the following algorithms are implemented:
- * - ENCR_AES_CBC
- * - ENCR_DES
- * - ENCR_3DES
- *
- * @ingroup crypters
+ * Encryption algorithm, as in IKEv2 RFC 3.3.2.
*/
enum encryption_algorithm_t {
ENCR_UNDEFINED = 1024,
ENCR_DES_IV64 = 1,
- /** Implemented in class des_crypter_t */
ENCR_DES = 2,
- /** Implemented in class des_crypter_t */
ENCR_3DES = 3,
ENCR_RC5 = 4,
ENCR_IDEA = 5,
@@ -53,9 +44,14 @@ enum encryption_algorithm_t {
ENCR_3IDEA = 8,
ENCR_DES_IV32 = 9,
ENCR_NULL = 11,
- /** Implemented in class aes_cbc_crypter_t */
ENCR_AES_CBC = 12,
- ENCR_AES_CTR = 13
+ ENCR_AES_CTR = 13,
+ ENCR_AES_CCM_ICV8 = 14,
+ ENCR_AES_CCM_ICV12 = 15,
+ ENCR_AES_CCM_ICV16 = 16,
+ ENCR_AES_GCM_ICV8 = 18,
+ ENCR_AES_GCM_ICV12 = 19,
+ ENCR_AES_GCM_ICV16 = 20
};
/**
@@ -64,92 +60,65 @@ enum encryption_algorithm_t {
extern enum_name_t *encryption_algorithm_names;
/**
- * @brief Generic interface for symmetric encryption algorithms.
- *
- * @b Constructors:
- * - crypter_create()
- *
- * @ingroup crypters
+ * Generic interface for symmetric encryption algorithms.
*/
struct crypter_t {
/**
- * @brief Encrypt a chunk of data and allocate space for the encrypted value.
+ * Encrypt a chunk of data and allocate space for the encrypted value.
*
- * @param this calling object
- * @param data data to encrypt
- * @param iv initializing vector
- * @param[out] encrypted pointer where the encrypted bytes will be written
- * @return
- * - SUCCESS
- * - INVALID_ARG if data size not a multiple of block size
+ * The length of the iv must equal to get_block_size(), while the length
+ * of data must be a multiple it.
+ * If encrypted is NULL, the encryption is done in-place (overwriting data).
+ *
+ * @param data data to encrypt
+ * @param iv initializing vector
+ * @param encrypted chunk to allocate encrypted data, or NULL
*/
- status_t (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted);
+ void (*encrypt) (crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *encrypted);
/**
- * @brief Decrypt a chunk of data and allocate space for the decrypted value.
+ * Decrypt a chunk of data and allocate space for the decrypted value.
+ *
+ * The length of the iv must equal to get_block_size(), while the length
+ * of data must be a multiple it.
+ * If decrpyted is NULL, the encryption is done in-place (overwriting data).
*
- * @param this calling object
- * @param data data to decrypt
- * @param iv initializing vector
- * @param[out] encrypted pointer where the decrypted bytes will be written
- * @return
- * - SUCCESS
- * - INVALID_ARG if data size not a multiple of block size
+ * @param data data to decrypt
+ * @param iv initializing vector
+ * @param encrypted chunk to allocate decrypted data, or NULL
*/
- status_t (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted);
+ void (*decrypt) (crypter_t *this, chunk_t data, chunk_t iv,
+ chunk_t *decrypted);
/**
- * @brief Get the block size of this crypter_t object.
+ * Get the block size of the crypto algorithm.
*
- * @param this calling object
* @return block size in bytes
*/
size_t (*get_block_size) (crypter_t *this);
/**
- * @brief Get the key size of this crypter_t object.
+ * Get the key size of the crypto algorithm.
*
- * @param this calling object
* @return key size in bytes
*/
size_t (*get_key_size) (crypter_t *this);
/**
- * @brief Set the key for this crypter_t object.
- *
- * @param this calling object
+ * Set the key.
+ *
+ * The length of the key must match get_key_size().
+ *
* @param key key to set
- * @return
- * - SUCCESS
- * - INVALID_ARG if key length invalid
*/
- status_t (*set_key) (crypter_t *this, chunk_t key);
+ void (*set_key) (crypter_t *this, chunk_t key);
/**
- * @brief Destroys a crypter_t object.
- *
- * @param this calling object
+ * Destroys a crypter_t object.
*/
void (*destroy) (crypter_t *this);
};
-/**
- * @brief Generic constructor for crypter_t objects.
- *
- * Currently only the following algorithms are implemented:
- * - ENCR_AES_CBC
- * - ENCR_DES
- * - ENCR_3DES
- *
- * The key_size is ignored for algorithms with fixed key size.
- *
- * @param encryption_algorithm Algorithm to use for crypter
- * @param key_size size of the key in bytes
- * @return
- * - crypter_t object
- * - NULL if encryption algorithm/key_size is not supported
- */
-crypter_t *crypter_create(encryption_algorithm_t encryption_algorithm, size_t key_size);
-
-#endif /*CRYPTER_H_*/
+#endif /*CRYPTER_H_ @} */
diff --git a/src/libstrongswan/crypto/crypters/des_crypter.c b/src/libstrongswan/crypto/crypters/des_crypter.c
deleted file mode 100644
index 655cc03ce..000000000
--- a/src/libstrongswan/crypto/crypters/des_crypter.c
+++ /dev/null
@@ -1,1536 +0,0 @@
-/**
- * @file des_crypter.c
- *
- * @brief Implementation of des_crypter_t
- *
- */
-
-/* Copyright (C) 2006 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * Derived from Plutos DES library by Eric Young.
- *
- * 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.
- *
- * 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_crypter.h"
-
-typedef u_char des_cblock[8];
-
-typedef struct des_ks_struct {
- des_cblock _;
-} des_key_schedule[16];
-
-
-typedef struct private_des_crypter_t private_des_crypter_t;
-
-/**
- * Private data for des_crypter_t
- */
-struct private_des_crypter_t {
-
- /**
- * Public part of this class.
- */
- des_crypter_t public;
-
- /**
- * Key size, depends on algoritm...
- */
- size_t key_size;
-
- union {
- /** key schedule for single des */
- des_key_schedule ks;
- /** key schedule for 3des */
- des_key_schedule ks3[3];
- };
-};
-
-
-#define DES_ENCRYPT 1
-#define DES_DECRYPT 0
-
-#define DES_LONG u_int32_t
-
-#if defined(WIN32) || defined(WIN16)
-#ifndef MSDOS
-#define MSDOS
-#endif
-#endif
-
-#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 dependancies 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 mucy CPU dependant */
-#ifndef DES_UNROLL
-#define DES_UNROLL
-#endif
-
-/* These default values were supplied by
- * Peter Gutman <pgut001@cs.auckland.ac.nz>
- * 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 ) /* x86 boxes, should be gcc */
-#define DES_PTR
-#define DES_RISC1
-#define DES_UNROLL
-#endif /* Systems-specific speed defines */
-#endif
-
-#endif /* DES_DEFAULT_OPTIONS */
-
-#ifdef MSDOS /* Visual C++ 2.1 (Windows NT/95) */
-#include <stdlib.h>
-#include <errno.h>
-#include <time.h>
-#include <io.h>
-#ifndef RAND
-#define RAND
-#endif
-#undef NOPROTO
-#endif
-
-#if defined(__STDC__) || defined(VMS) || defined(M_XENIX) || defined(MSDOS)
-#ifndef __KERNEL__
-#include <string.h>
-#else
-#include <linux/string.h>
-#endif
-#endif
-
-#ifndef RAND
-#define RAND
-#endif
-
-#ifdef linux
-#undef RAND
-#endif
-
-#ifdef MSDOS
-#define getpid() 2
-#define RAND
-#undef NOPROTO
-#endif
-
-#if defined(NOCONST)
-#define const
-#endif
-
-#ifdef __STDC__
-#undef NOPROTO
-#endif
-
-#ifdef RAND
-#define srandom(s) srand(s)
-#define random rand
-#endif
-
-#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); \
-} \
-}
-
-#if defined(WIN32)
-#define ROTATE(a,n) (_lrotr(a,n))
-#else
-#define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n))))
-#endif
-
-/* 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 achitecture. gcc2 always seems to do well :-).
- * Inspired by Dana How <how@isl.stanford.edu>
- * 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 occured 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^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
- u3=(int)(u>>8L); \
- u1=(int)u&0xfc; \
- u3&=0xfc; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+u1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+u3); \
- u2=(int)t>>8L; \
- u1=(int)t&0xfc; \
- u2&=0xfc; \
- t>>=16L; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
- u3=(int)t>>8L; \
- u1=(int)t&0xfc; \
- u3&=0xfc; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+u1); \
- LL^= *(DES_LONG *)((unsigned char *)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^= *(DES_LONG *)((unsigned char *)des_SP +u1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x200+u2); \
- s1=(int)(u>>16L); \
- s2=(int)(u>>24L); \
- s1&=0xfc; \
- s2&=0xfc; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x400+s1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x600+s2); \
- u2=(int)t>>8L; \
- u1=(int)t&0xfc; \
- u2&=0xfc; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x100+u1); \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x300+u2); \
- s1=(int)(t>>16L); \
- s2=(int)(t>>24L); \
- s1&=0xfc; \
- s2&=0xfc; \
- LL^= *(DES_LONG *)((unsigned char *)des_SP+0x500+s1); \
- LL^= *(DES_LONG *)((unsigned char *)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^= \
- *(DES_LONG *)((unsigned char *)des_SP +((u )&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x200+((u>> 8L)&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x400+((u>>16L)&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x600+((u>>24L)&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x100+((t )&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x300+((t>> 8L)&0xfc))^ \
- *(DES_LONG *)((unsigned char *)des_SP+0x500+((t>>16L)&0xfc))^ \
- *(DES_LONG *)((unsigned char *)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<<size);
- can be used to swap and move bits between words.
-
- So l = 0 1 2 3 r = 16 17 18 19
- 4 5 6 7 20 21 22 23
- 8 9 10 11 24 25 26 27
- 12 13 14 15 28 29 30 31
- becomes (for size == 2 and mask == 0x3333)
- t = 2^16 3^17 -- -- l = 0 1 16 17 r = 2 3 18 19
- 6^20 7^21 -- -- 4 5 20 21 6 7 22 23
- 10^24 11^25 -- -- 8 9 24 25 10 11 24 25
- 14^28 15^29 -- -- 12 13 28 29 14 15 28 29
-
- Thanks for hints from Richard Outerbridge - he told me IP&FP
- could be done in 15 xor, 10 shifts and 5 ands.
- When I finally started to think of the problem in 2D
- I first got ~42 operations without xors. When I remembered
- how to use xors :-) I got it to its final state.
- */
-#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\
- (b)^=(t),\
- (a)^=((t)<<(n)))
-
-#define IP(l,r) \
-{ \
- register 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) \
-{ \
- register 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); \
-}
-
-#ifndef NOPROTO
-void fcrypt_body(DES_LONG *out,des_key_schedule ks,
- DES_LONG Eswap0, DES_LONG Eswap1);
-#else
-void fcrypt_body();
-#endif
-
-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,
- }
-};
-
-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,
- }
-};
-
-#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\
- (a)=(a)^(t)^(t>>(16-(n))))
-
-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
-};
-
-/**
- * Create key schedule for a single DES 64Bit key
- */
-static int des_set_key(des_cblock *key, des_key_schedule *schedule)
-{
- static int shifts2[16] = {0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0};
- register DES_LONG c,d,t,s,t2;
- register unsigned char *in;
- register DES_LONG *k;
- register int i;
- des_cblock odd;
-
- for (i = 0; i < sizeof(des_cblock); i++)
- {
- odd[i] = odd_parity[(*key)[i]];
- }
-
- k=(DES_LONG *)schedule;
- in=(unsigned char *)&odd;
-
- c2l(in,c);
- c2l(in,d);
-
- /* do PC1 in 60 simple operations */
-/* PERM_OP(d,c,t,4,0x0f0f0f0fL);
- HPERM_OP(c,t,-2, 0xcccc0000L);
- HPERM_OP(c,t,-1, 0xaaaa0000L);
- HPERM_OP(c,t, 8, 0x00ff0000L);
- HPERM_OP(c,t,-1, 0xaaaa0000L);
- HPERM_OP(d,t,-8, 0xff000000L);
- HPERM_OP(d,t, 8, 0x00ff0000L);
- HPERM_OP(d,t, 2, 0x33330000L);
- d=((d&0x00aa00aaL)<<7L)|((d&0x55005500L)>>7L)|(d&0xaa55aa55L);
- d=(d>>8)|((c&0xf0000000L)>>4);
- c&=0x0fffffffL; */
-
- /* I now do it 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>> 6)&0x03)|((c>> 7L)&0x3c)]|
- des_skb[2][((c>>13)&0x0f)|((c>>14L)&0x30)]|
- des_skb[3][((c>>20)&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;
- }
- return(0);
-}
-
-
-static void des_encrypt(DES_LONG *data, des_key_schedule ks, int enc)
-{
- register DES_LONG l,r,t,u;
-#ifdef DES_PTR
- register unsigned char *des_SP=(unsigned char *)des_SPtrans;
-#endif
-#ifndef DES_UNROLL
- register int i;
-#endif
- register 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=(DES_LONG *)ks;
- /* 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+=8)
-{
- D_ENCRYPT(l,r,i+0); /* 1 */
- D_ENCRYPT(r,l,i+2); /* 2 */
- D_ENCRYPT(l,r,i+4); /* 3 */
- D_ENCRYPT(r,l,i+6); /* 4 */
-}
-#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-=8)
-{
- D_ENCRYPT(l,r,i-0); /* 16 */
- D_ENCRYPT(r,l,i-2); /* 15 */
- D_ENCRYPT(l,r,i-4); /* 14 */
- D_ENCRYPT(r,l,i-6); /* 13 */
-}
-#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;
-}
-
-/**
- * DES CBC encrypt decrypt routine
- */
-static void des_cbc_encrypt(des_cblock *input, des_cblock *output, long length,
- des_key_schedule schedule, des_cblock *ivec, int enc)
-{
- register DES_LONG tin0,tin1;
- register DES_LONG tout0,tout1,xor0,xor1;
- register unsigned char *in,*out;
- register long l=length;
- DES_LONG tin[2];
- unsigned char *iv;
-
- in=(unsigned char *)input;
- out=(unsigned char *)output;
- iv=(unsigned char *)ivec;
-
- 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_encrypt((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_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT);
- tout0=tin[0]; l2c(tout0,out);
- tout1=tin[1]; l2c(tout1,out);
- }
- }
- 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_encrypt((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_encrypt((DES_LONG *)tin,schedule,DES_DECRYPT);
- tout0=tin[0]^xor0;
- tout1=tin[1]^xor1;
- l2cn(tout0,tout1,out,l+8);
- /* xor0=tin0;
- xor1=tin1; */
- }
- }
- tin0=tin1=tout0=tout1=xor0=xor1=0;
- tin[0]=tin[1]=0;
-}
-
-static void des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc)
-{
- register DES_LONG l,r,t,u;
-#ifdef DES_PTR
- register unsigned char *des_SP=(unsigned char *)des_SPtrans;
-#endif
-#ifndef DES_UNROLL
- register int i;
-#endif
- register 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=(DES_LONG *)ks;
- /* 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+=8)
-{
- D_ENCRYPT(l,r,i+0); /* 1 */
- D_ENCRYPT(r,l,i+2); /* 2 */
- D_ENCRYPT(l,r,i+4); /* 3 */
- D_ENCRYPT(r,l,i+6); /* 4 */
-}
-#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-=8)
-{
- D_ENCRYPT(l,r,i-0); /* 16 */
- D_ENCRYPT(r,l,i-2); /* 15 */
- D_ENCRYPT(l,r,i-4); /* 14 */
- D_ENCRYPT(r,l,i-6); /* 13 */
-}
-#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;
-}
-
-/**
- * Single block 3DES EDE encrypt routine
- */
-static void des_encrypt3(DES_LONG *data, des_key_schedule ks1,
- des_key_schedule ks2, des_key_schedule ks3)
-{
- register 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;
-}
-
-/**
- * Single block 3DES EDE decrypt routine
- */
-static void des_decrypt3(DES_LONG *data, des_key_schedule ks1,
- des_key_schedule ks2, des_key_schedule ks3)
-{
- register 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;
-}
-
-/**
- * 3DES EDE CBC encrypt/decrypt routine
- */
-static void des_ede3_cbc_encrypt(des_cblock *input, des_cblock *output, long length,
- des_key_schedule ks1, des_key_schedule ks2,
- des_key_schedule ks3, des_cblock *ivec, int enc)
-{
- register DES_LONG tin0,tin1;
- register DES_LONG tout0,tout1,xor0,xor1;
- register unsigned char *in,*out;
- register long l=length;
- DES_LONG tin[2];
- unsigned char *iv;
-
- in=(unsigned char *)input;
- out=(unsigned char *)output;
- iv=(unsigned char *)ivec;
-
- 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=(unsigned char *)ivec;
- l2c(tout0,iv);
- l2c(tout1,iv);
- }
- else
- {
- register 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=(unsigned char *)ivec;
- l2c(xor0,iv);
- l2c(xor1,iv);
- }
- tin0=tin1=tout0=tout1=xor0=xor1=0;
- tin[0]=tin[1]=0;
-}
-
-/**
- * Implementation of crypter_t.decrypt for DES.
- */
-static status_t decrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
-{
- des_cblock ivb;
-
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
- *decrypted = chunk_alloc(data.len);
- memcpy(&ivb, iv.ptr, sizeof(des_cblock));
- des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(decrypted->ptr),
- data.len, this->ks, &ivb, DES_DECRYPT);
- return SUCCESS;
-}
-
-
-/**
- * Implementation of crypter_t.decrypt for DES.
- */
-static status_t encrypt(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
-{
- des_cblock ivb;
-
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
- *encrypted = chunk_alloc(data.len);
- memcpy(&ivb, iv.ptr, sizeof(des_cblock));
- des_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(encrypted->ptr),
- data.len, this->ks, &ivb, DES_ENCRYPT);
- return SUCCESS;
-}
-
-/**
- * Implementation of crypter_t.decrypt for 3DES.
- */
-static status_t decrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *decrypted)
-{
- des_cblock ivb;
-
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
- *decrypted = chunk_alloc(data.len);
- memcpy(&ivb, iv.ptr, sizeof(des_cblock));
- des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(decrypted->ptr),
- data.len, this->ks3[0], this->ks3[1], this->ks3[2],
- &ivb, DES_DECRYPT);
- return SUCCESS;
-}
-
-/**
- * Implementation of crypter_t.decrypt for 3DES.
- */
-static status_t encrypt3(private_des_crypter_t *this, chunk_t data, chunk_t iv, chunk_t *encrypted)
-{
- des_cblock ivb;
-
- if (data.len % sizeof(des_cblock) != 0 ||
- iv.len != sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
- *encrypted = chunk_alloc(data.len);
- memcpy(&ivb, iv.ptr, sizeof(des_cblock));
- des_ede3_cbc_encrypt((des_cblock*)(data.ptr), (des_cblock*)(encrypted->ptr),
- data.len, this->ks3[0], this->ks3[1], this->ks3[2],
- &ivb, DES_ENCRYPT);
- return SUCCESS;
-}
-
-/**
- * Implementation of crypter_t.get_block_size.
- */
-static size_t get_block_size (private_des_crypter_t *this)
-{
- return sizeof(des_cblock);
-}
-
-/**
- * Implementation of crypter_t.get_key_size.
- */
-static size_t get_key_size (private_des_crypter_t *this)
-{
- return this->key_size;
-}
-
-/**
- * Implementation of crypter_t.set_key for DES.
- */
-static status_t set_key(private_des_crypter_t *this, chunk_t key)
-{
- if (key.len != sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
- des_set_key((des_cblock*)(key.ptr), &this->ks);
-
- return SUCCESS;
-}
-
-/**
- * Implementation of crypter_t.set_key for 3DES.
- */
-static status_t set_key3(private_des_crypter_t *this, chunk_t key)
-{
- if (key.len != 3 * sizeof(des_cblock))
- {
- return INVALID_ARG;
- }
-
- des_set_key((des_cblock*)(key.ptr) + 0, &this->ks3[0]);
- des_set_key((des_cblock*)(key.ptr) + 1, &this->ks3[1]);
- des_set_key((des_cblock*)(key.ptr) + 2, &this->ks3[2]);
-
- return SUCCESS;
-}
-
-/**
- * Implementation of crypter_t.destroy and des_crypter_t.destroy.
- */
-static void destroy(private_des_crypter_t *this)
-{
- free(this);
-}
-
-/*
- * Described in header
- */
-des_crypter_t *des_crypter_create(encryption_algorithm_t algo)
-{
- private_des_crypter_t *this = malloc_thing(private_des_crypter_t);
-
- /* functions of crypter_t interface */
- this->public.crypter_interface.get_block_size = (size_t (*) (crypter_t *)) get_block_size;
- this->public.crypter_interface.get_key_size = (size_t (*) (crypter_t *)) get_key_size;
- this->public.crypter_interface.destroy = (void (*) (crypter_t *)) destroy;
-
- /* use functions depending on algorithm */
- switch (algo)
- {
- case ENCR_DES:
- this->key_size = sizeof(des_cblock);
- this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key;
- this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt;
- this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt;
- break;
- case ENCR_3DES:
- this->key_size = 3 * sizeof(des_cblock);
- this->public.crypter_interface.set_key = (status_t (*) (crypter_t *,chunk_t)) set_key3;
- this->public.crypter_interface.encrypt = (status_t (*) (crypter_t *, chunk_t,chunk_t, chunk_t *)) encrypt3;
- this->public.crypter_interface.decrypt = (status_t (*) (crypter_t *, chunk_t , chunk_t, chunk_t *)) decrypt3;
- break;
- default:
- free(this);
- return NULL;
- }
- return &(this->public);
-}
diff --git a/src/libstrongswan/crypto/crypters/des_crypter.h b/src/libstrongswan/crypto/crypters/des_crypter.h
deleted file mode 100644
index 0c87b0a9c..000000000
--- a/src/libstrongswan/crypto/crypters/des_crypter.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file des_crypter.h
- *
- * @brief Interface of des_crypter_t
- *
- */
-
-/*
- * Copyright (C) 2006 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef DES_CRYPTER_H_
-#define DES_CRYPTER_H_
-
-typedef struct des_crypter_t des_crypter_t;
-
-#include <crypto/crypters/crypter.h>
-
-
-/**
- * @brief Class implementing the DES and 3DES encryption algorithms.
- *
- * @b Constructors:
- * - des_crypter_create()
- *
- * @ingroup crypters
- */
-struct des_crypter_t {
-
- /**
- * The crypter_t interface.
- */
- crypter_t crypter_interface;
-};
-
-/**
- * @brief Constructor to create des_crypter_t objects.
- *
- * @param algo ENCR_DES for single DES, ENCR_3DES for triple DES
- * @return
- * - des_crypter_t object
- * - NULL if algo not supported
- */
-des_crypter_t *des_crypter_create(encryption_algorithm_t algo);
-
-
-#endif /* DES_CRYPTER_H_ */
diff --git a/src/libstrongswan/crypto/crypto_factory.c b/src/libstrongswan/crypto/crypto_factory.c
new file mode 100644
index 000000000..46fa983b2
--- /dev/null
+++ b/src/libstrongswan/crypto/crypto_factory.c
@@ -0,0 +1,571 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ *
+ * $Id: crypto_factory.c 3806 2008-04-15 05:56:35Z martin $
+ */
+
+#include "crypto_factory.h"
+
+#include <utils/linked_list.h>
+#include <utils/mutex.h>
+
+typedef struct crypter_entry_t crypter_entry_t;
+struct crypter_entry_t {
+ /** encryption algorithm */
+ encryption_algorithm_t algo;
+ /** associated constructor */
+ crypter_constructor_t create;
+};
+
+typedef struct signer_entry_t signer_entry_t;
+struct signer_entry_t {
+ /** integrity algorithm */
+ integrity_algorithm_t algo;
+ /** associated constructor */
+ signer_constructor_t create;
+};
+
+typedef struct hasher_entry_t hasher_entry_t;
+struct hasher_entry_t {
+ /** hash algorithm */
+ hash_algorithm_t algo;
+ /** associated constructor */
+ hasher_constructor_t create;
+};
+
+typedef struct prf_entry_t prf_entry_t;
+struct prf_entry_t {
+ /** hash algorithm */
+ pseudo_random_function_t algo;
+ /** associated constructor */
+ prf_constructor_t create;
+};
+
+typedef struct rng_entry_t rng_entry_t;
+struct rng_entry_t {
+ /** quality of randomness */
+ rng_quality_t quality;
+ /** associated constructor */
+ rng_constructor_t create;
+};
+
+typedef struct dh_entry_t dh_entry_t;
+struct dh_entry_t {
+ /** hash algorithm */
+ diffie_hellman_group_t group;
+ /** associated constructor */
+ dh_constructor_t create;
+};
+
+typedef struct private_crypto_factory_t private_crypto_factory_t;
+
+/**
+ * private data of crypto_factory
+ */
+struct private_crypto_factory_t {
+
+ /**
+ * public functions
+ */
+ crypto_factory_t public;
+
+ /**
+ * registered crypters, as crypter_entry_t
+ */
+ linked_list_t *crypters;
+
+ /**
+ * registered signers, as signer_entry_t
+ */
+ linked_list_t *signers;
+
+ /**
+ * registered hashers, as hasher_entry_t
+ */
+ linked_list_t *hashers;
+
+ /**
+ * registered prfs, as prf_entry_t
+ */
+ linked_list_t *prfs;
+
+ /**
+ * registered rngs, as rng_entry_t
+ */
+ linked_list_t *rngs;
+
+ /**
+ * registered diffie hellman, as dh_entry_t
+ */
+ linked_list_t *dhs;
+
+ /**
+ * mutex to lock access to modules
+ */
+ mutex_t *mutex;
+};
+
+/**
+ * Implementation of crypto_factory_t.create_crypter.
+ */
+static crypter_t* create_crypter(private_crypto_factory_t *this,
+ encryption_algorithm_t algo, size_t key_size)
+{
+ enumerator_t *enumerator;
+ crypter_entry_t *entry;
+ crypter_t *crypter = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->crypters->create_enumerator(this->crypters);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->algo == algo)
+ {
+ crypter = entry->create(algo, key_size);
+ if (crypter)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return crypter;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_signer.
+ */
+static signer_t* create_signer(private_crypto_factory_t *this,
+ integrity_algorithm_t algo)
+{
+ enumerator_t *enumerator;
+ signer_entry_t *entry;
+ signer_t *signer = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->signers->create_enumerator(this->signers);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->algo == algo)
+ {
+ signer = entry->create(algo);
+ if (signer)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+
+ return signer;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_hasher.
+ */
+static hasher_t* create_hasher(private_crypto_factory_t *this,
+ hash_algorithm_t algo)
+{
+ enumerator_t *enumerator;
+ hasher_entry_t *entry;
+ hasher_t *hasher = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->hashers->create_enumerator(this->hashers);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (algo == HASH_PREFERRED || entry->algo == algo)
+ {
+ hasher = entry->create(entry->algo);
+ if (hasher)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return hasher;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_prf.
+ */
+static prf_t* create_prf(private_crypto_factory_t *this,
+ pseudo_random_function_t algo)
+{
+ enumerator_t *enumerator;
+ prf_entry_t *entry;
+ prf_t *prf = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->prfs->create_enumerator(this->prfs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->algo == algo)
+ {
+ prf = entry->create(algo);
+ if (prf)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return prf;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_rng.
+ */
+static rng_t* create_rng(private_crypto_factory_t *this, rng_quality_t quality)
+{
+ enumerator_t *enumerator;
+ rng_entry_t *entry;
+ u_int diff = ~0;
+ rng_constructor_t constr = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->rngs->create_enumerator(this->rngs);
+ while (enumerator->enumerate(enumerator, &entry))
+ { /* find the best matching quality, but at least as good as requested */
+ if (entry->quality >= quality && diff > entry->quality - quality)
+ {
+ diff = entry->quality - quality;
+ constr = entry->create;
+ if (diff == 0)
+ { /* perfect match, won't get better */
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ if (constr)
+ {
+ return constr(quality);
+ }
+ return NULL;
+}
+
+/**
+ * Implementation of crypto_factory_t.create_dh.
+ */
+static diffie_hellman_t* create_dh(private_crypto_factory_t *this,
+ diffie_hellman_group_t group)
+{
+ enumerator_t *enumerator;
+ dh_entry_t *entry;
+ diffie_hellman_t *diffie_hellman = NULL;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->dhs->create_enumerator(this->dhs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->group == group)
+ {
+ diffie_hellman = entry->create(group);
+ if (diffie_hellman)
+ {
+ break;
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+ return diffie_hellman;
+}
+
+/**
+ * Implementation of crypto_factory_t.add_crypter.
+ */
+static void add_crypter(private_crypto_factory_t *this,
+ encryption_algorithm_t algo,
+ crypter_constructor_t create)
+{
+ crypter_entry_t *entry = malloc_thing(crypter_entry_t);
+
+ entry->algo = algo;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->crypters->insert_last(this->crypters, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_crypter.
+ */
+static void remove_crypter(private_crypto_factory_t *this,
+ crypter_constructor_t create)
+{
+ crypter_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->crypters->create_enumerator(this->crypters);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->crypters->remove_at(this->crypters, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_signer.
+ */
+static void add_signer(private_crypto_factory_t *this,
+ integrity_algorithm_t algo, signer_constructor_t create)
+{
+ signer_entry_t *entry = malloc_thing(signer_entry_t);
+
+ entry->algo = algo;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->signers->insert_last(this->signers, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_signer.
+ */
+static void remove_signer(private_crypto_factory_t *this,
+ signer_constructor_t create)
+{
+ signer_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->signers->create_enumerator(this->signers);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->signers->remove_at(this->signers, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_hasher.
+ */
+static void add_hasher(private_crypto_factory_t *this, hash_algorithm_t algo,
+ hasher_constructor_t create)
+{
+ hasher_entry_t *entry = malloc_thing(hasher_entry_t);
+
+ entry->algo = algo;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->hashers->insert_last(this->hashers, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_hasher.
+ */
+static void remove_hasher(private_crypto_factory_t *this,
+ hasher_constructor_t create)
+{
+ hasher_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->hashers->create_enumerator(this->hashers);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->hashers->remove_at(this->hashers, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_prf.
+ */
+static void add_prf(private_crypto_factory_t *this,
+ pseudo_random_function_t algo, prf_constructor_t create)
+{
+ prf_entry_t *entry = malloc_thing(prf_entry_t);
+
+ entry->algo = algo;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->prfs->insert_last(this->prfs, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_prf.
+ */
+static void remove_prf(private_crypto_factory_t *this, prf_constructor_t create)
+{
+ prf_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->prfs->create_enumerator(this->prfs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->prfs->remove_at(this->prfs, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_rng.
+ */
+static void add_rng(private_crypto_factory_t *this, rng_quality_t quality,
+ rng_constructor_t create)
+{
+ rng_entry_t *entry = malloc_thing(rng_entry_t);
+
+ entry->quality = quality;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->rngs->insert_last(this->rngs, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_rng.
+ */
+static void remove_rng(private_crypto_factory_t *this, rng_constructor_t create)
+{
+ rng_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->rngs->create_enumerator(this->rngs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->rngs->remove_at(this->rngs, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.add_dh.
+ */
+static void add_dh(private_crypto_factory_t *this, diffie_hellman_group_t group,
+ dh_constructor_t create)
+{
+ dh_entry_t *entry = malloc_thing(dh_entry_t);
+
+ entry->group = group;
+ entry->create = create;
+ this->mutex->lock(this->mutex);
+ this->dhs->insert_last(this->dhs, entry);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.remove_dh.
+ */
+static void remove_dh(private_crypto_factory_t *this, dh_constructor_t create)
+{
+ dh_entry_t *entry;
+ enumerator_t *enumerator;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->dhs->create_enumerator(this->dhs);
+ while (enumerator->enumerate(enumerator, &entry))
+ {
+ if (entry->create == create)
+ {
+ this->dhs->remove_at(this->dhs, enumerator);
+ free(entry);
+ }
+ }
+ enumerator->destroy(enumerator);
+ this->mutex->unlock(this->mutex);
+}
+
+/**
+ * Implementation of crypto_factory_t.destroy
+ */
+static void destroy(private_crypto_factory_t *this)
+{
+ this->crypters->destroy_function(this->crypters, free);
+ this->signers->destroy_function(this->signers, free);
+ this->hashers->destroy_function(this->hashers, free);
+ this->prfs->destroy_function(this->prfs, free);
+ this->rngs->destroy_function(this->rngs, free);
+ this->dhs->destroy_function(this->dhs, free);
+ this->mutex->destroy(this->mutex);
+ free(this);
+}
+
+/*
+ * see header file
+ */
+crypto_factory_t *crypto_factory_create()
+{
+ private_crypto_factory_t *this = malloc_thing(private_crypto_factory_t);
+
+ this->public.create_crypter = (crypter_t*(*)(crypto_factory_t*, encryption_algorithm_t, size_t))create_crypter;
+ this->public.create_signer = (signer_t*(*)(crypto_factory_t*, integrity_algorithm_t))create_signer;
+ this->public.create_hasher = (hasher_t*(*)(crypto_factory_t*, hash_algorithm_t))create_hasher;
+ this->public.create_prf = (prf_t*(*)(crypto_factory_t*, pseudo_random_function_t))create_prf;
+ this->public.create_rng = (rng_t*(*)(crypto_factory_t*, rng_quality_t quality))create_rng;
+ this->public.create_dh = (diffie_hellman_t*(*)(crypto_factory_t*, diffie_hellman_group_t group))create_dh;
+ this->public.add_crypter = (void(*)(crypto_factory_t*, encryption_algorithm_t algo, crypter_constructor_t create))add_crypter;
+ this->public.remove_crypter = (void(*)(crypto_factory_t*, crypter_constructor_t create))remove_crypter;
+ this->public.add_signer = (void(*)(crypto_factory_t*, integrity_algorithm_t algo, signer_constructor_t create))add_signer;
+ this->public.remove_signer = (void(*)(crypto_factory_t*, signer_constructor_t create))remove_signer;
+ this->public.add_hasher = (void(*)(crypto_factory_t*, hash_algorithm_t algo, hasher_constructor_t create))add_hasher;
+ this->public.remove_hasher = (void(*)(crypto_factory_t*, hasher_constructor_t create))remove_hasher;
+ this->public.add_prf = (void(*)(crypto_factory_t*, pseudo_random_function_t algo, prf_constructor_t create))add_prf;
+ this->public.remove_prf = (void(*)(crypto_factory_t*, prf_constructor_t create))remove_prf;
+ this->public.add_rng = (void(*)(crypto_factory_t*, rng_quality_t quality, rng_constructor_t create))add_rng;
+ this->public.remove_rng = (void(*)(crypto_factory_t*, rng_constructor_t create))remove_rng;
+ this->public.add_dh = (void(*)(crypto_factory_t*, diffie_hellman_group_t algo, dh_constructor_t create))add_dh;
+ this->public.remove_dh = (void(*)(crypto_factory_t*, dh_constructor_t create))remove_dh;
+ this->public.destroy = (void(*)(crypto_factory_t*))destroy;
+
+ this->crypters = linked_list_create();
+ this->signers = linked_list_create();
+ this->hashers = linked_list_create();
+ this->prfs = linked_list_create();
+ this->rngs = linked_list_create();
+ this->dhs = linked_list_create();
+ this->mutex = mutex_create(MUTEX_RECURSIVE);
+
+ return &this->public;
+}
+
diff --git a/src/libstrongswan/crypto/crypto_factory.h b/src/libstrongswan/crypto/crypto_factory.h
new file mode 100644
index 000000000..6bf070c31
--- /dev/null
+++ b/src/libstrongswan/crypto/crypto_factory.h
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ */
+
+/**
+ * @defgroup crypto_factory crypto_factory
+ * @{ @ingroup crypto
+ */
+
+#ifndef CRYPTO_FACTORY_H_
+#define CRYPTO_FACTORY_H_
+
+typedef struct crypto_factory_t crypto_factory_t;
+
+#include <library.h>
+#include <crypto/crypters/crypter.h>
+#include <crypto/signers/signer.h>
+#include <crypto/hashers/hasher.h>
+#include <crypto/prfs/prf.h>
+#include <crypto/rngs/rng.h>
+#include <crypto/diffie_hellman.h>
+
+/**
+ * Constructor function for crypters
+ */
+typedef crypter_t* (*crypter_constructor_t)(encryption_algorithm_t algo,
+ size_t key_size);
+/**
+ * Constructor function for signers
+ */
+typedef signer_t* (*signer_constructor_t)(integrity_algorithm_t algo);
+
+/**
+ * Constructor function for hashers
+ */
+typedef hasher_t* (*hasher_constructor_t)(hash_algorithm_t algo);
+
+/**
+ * Constructor function for pseudo random functions
+ */
+typedef prf_t* (*prf_constructor_t)(pseudo_random_function_t algo);
+
+/**
+ * Constructor function for source of randomness
+ */
+typedef rng_t* (*rng_constructor_t)(rng_quality_t quality);
+
+/**
+ * Constructor function for diffie hellman
+ */
+typedef diffie_hellman_t* (*dh_constructor_t)(diffie_hellman_group_t group);
+
+/**
+ * Handles crypto modules and creates instances.
+ */
+struct crypto_factory_t {
+
+ /**
+ * Create a crypter instance.
+ *
+ * @param algo encryption algorithm
+ * @param key_size length of the key in bytes
+ * @return crypter_t instance, NULL if not supported
+ */
+ crypter_t* (*create_crypter)(crypto_factory_t *this,
+ encryption_algorithm_t algo, size_t key_size);
+
+ /**
+ * Create a symmetric signer instance.
+ *
+ * @param algo MAC algorithm to use
+ * @return signer_t instance, NULL if not supported
+ */
+ signer_t* (*create_signer)(crypto_factory_t *this,
+ integrity_algorithm_t algo);
+
+ /**
+ * Create a hasher instance.
+ *
+ * @param algo hash algorithm
+ * @return hasher_t instance, NULL if not supported
+ */
+ hasher_t* (*create_hasher)(crypto_factory_t *this, hash_algorithm_t algo);
+
+ /**
+ * Create a pseudo random function instance.
+ *
+ * @param algo PRF algorithm to use
+ * @return prf_t instance, NULL if not supported
+ */
+ prf_t* (*create_prf)(crypto_factory_t *this, pseudo_random_function_t algo);
+
+ /**
+ * Create a source of randomness.
+ *
+ * @param quality required randomness quality
+ * @return rng_t instance, NULL if no RNG with such a quality
+ */
+ rng_t* (*create_rng)(crypto_factory_t *this, rng_quality_t quality);
+
+ /**
+ * Create a diffie hellman instance.
+ *
+ * @param group diffie hellman group
+ * @return diffie_hellman_t instance, NULL if not supported
+ */
+ diffie_hellman_t* (*create_dh)(crypto_factory_t *this,
+ diffie_hellman_group_t group);
+
+ /**
+ * Register a crypter constructor.
+ *
+ * @param algo algorithm to constructor
+ * @param create constructor function for that algorithm
+ * @return
+ */
+ void (*add_crypter)(crypto_factory_t *this, encryption_algorithm_t algo,
+ crypter_constructor_t create);
+
+ /**
+ * Unregister a crypter constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_crypter)(crypto_factory_t *this, crypter_constructor_t create);
+
+ /**
+ * Register a signer constructor.
+ *
+ * @param algo algorithm to constructor
+ * @param create constructor function for that algorithm
+ * @return
+ */
+ void (*add_signer)(crypto_factory_t *this, integrity_algorithm_t algo,
+ signer_constructor_t create);
+
+ /**
+ * Unregister a signer constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_signer)(crypto_factory_t *this, signer_constructor_t create);
+
+ /**
+ * Register a hasher constructor.
+ *
+ * The first added hasher is the preferred hasher returned on
+ * create_hasher(HASH_PREFERRED).
+ *
+ * @param algo algorithm to constructor
+ * @param create constructor function for that algorithm
+ * @return
+ */
+ void (*add_hasher)(crypto_factory_t *this, hash_algorithm_t algo,
+ hasher_constructor_t create);
+
+ /**
+ * Unregister a hasher constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_hasher)(crypto_factory_t *this, hasher_constructor_t create);
+
+ /**
+ * Register a prf constructor.
+ *
+ * @param algo algorithm to constructor
+ * @param create constructor function for that algorithm
+ * @return
+ */
+ void (*add_prf)(crypto_factory_t *this, pseudo_random_function_t algo,
+ prf_constructor_t create);
+
+ /**
+ * Unregister a prf constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_prf)(crypto_factory_t *this, prf_constructor_t create);
+
+ /**
+ * Register a source of randomness.
+ *
+ * @param quality quality of randomness this RNG serves
+ * @param create constructor function for such a quality
+ */
+ void (*add_rng)(crypto_factory_t *this, rng_quality_t quality, rng_constructor_t create);
+
+ /**
+ * Unregister a source of randomness.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_rng)(crypto_factory_t *this, rng_constructor_t create);
+
+ /**
+ * Register a diffie hellman constructor.
+ *
+ * @param group dh group to constructor
+ * @param create constructor function for that algorithm
+ * @return
+ */
+ void (*add_dh)(crypto_factory_t *this, diffie_hellman_group_t group,
+ dh_constructor_t create);
+
+ /**
+ * Unregister a diffie hellman constructor.
+ *
+ * @param create constructor function to unregister
+ */
+ void (*remove_dh)(crypto_factory_t *this, dh_constructor_t create);
+
+ /**
+ * Destroy a crypto_factory instance.
+ */
+ void (*destroy)(crypto_factory_t *this);
+};
+
+/**
+ * Create a crypto_factory instance.
+ */
+crypto_factory_t *crypto_factory_create();
+
+#endif /* CRYPTO_FACTORY_H_ @}*/
diff --git a/src/libstrongswan/crypto/diffie_hellman.c b/src/libstrongswan/crypto/diffie_hellman.c
index 605892e87..02d2cb52a 100644
--- a/src/libstrongswan/crypto/diffie_hellman.c
+++ b/src/libstrongswan/crypto/diffie_hellman.c
@@ -1,14 +1,5 @@
-/**
- * @file diffie_hellman.c
- *
- * @brief Implementation of diffie_hellman_t.
- *
- */
-
/*
- * Copyright (C) 1998-2002 D. Hugh Redelmeier.
- * Copyright (C) 1999, 2000, 2001 Henry Spencer.
- * Copyright (C) 2005-2007 Martin Willi
+ * Copyright (C) 2005-2008 Martin Willi
* Copyright (C) 2005 Jan Hutter
* Hochschule fuer Technik Rapperswil
*
@@ -21,569 +12,29 @@
* 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.
+ *
+ * $Id: diffie_hellman.c 4023 2008-05-29 06:55:03Z andreas $
*/
-#include <gmp.h>
-
#include "diffie_hellman.h"
-#include <utils/randomizer.h>
-#include <debug.h>
-
ENUM_BEGIN(diffie_hellman_group_names, MODP_NONE, MODP_1024_BIT,
"MODP_NONE",
"MODP_768_BIT",
"MODP_1024_BIT");
ENUM_NEXT(diffie_hellman_group_names, MODP_1536_BIT, MODP_1536_BIT, MODP_1024_BIT,
"MODP_1536_BIT");
-ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, MODP_8192_BIT, MODP_1536_BIT,
+ENUM_NEXT(diffie_hellman_group_names, MODP_2048_BIT, ECP_521_BIT, MODP_1536_BIT,
"MODP_2048_BIT",
"MODP_3072_BIT",
"MODP_4096_BIT",
"MODP_6144_BIT",
- "MODP_8192_BIT");
-ENUM_END(diffie_hellman_group_names, MODP_8192_BIT);
-
-
-/**
- * Modulus of Group 1 (MODP_768_BIT).
- */
-static u_int8_t group1_modulus[] = {
- 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
-};
-
-/**
- * Modulus of Group 2 (MODP_1024_BIT).
- */
-static u_int8_t group2_modulus[] = {
- 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
-};
-
-/**
- * Modulus of Group 5 (MODP_1536_BIT).
- */
-static u_int8_t group5_modulus[] = {
- 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
-};
-/**
- * Modulus of Group 14 (MODP_2048_BIT).
- */
-static u_int8_t group14_modulus[] = {
- 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
-};
-
-/**
- * Modulus of Group 15 (MODP_3072_BIT).
- */
-static u_int8_t group15_modulus[] = {
- 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
-};
-
-/**
- * Modulus of Group 16 (MODP_4096_BIT).
- */
-static u_int8_t group16_modulus[] = {
- 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
-};
-
-/**
- * Modulus of Group 17 (MODP_6144_BIT).
- */
-static u_int8_t group17_modulus[] = {
- 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
-};
-
-/**
- * Modulus of Group 18 (MODP_8192_BIT).
- */
-static u_int8_t group18_modulus[] = {
- 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,
-};
-
-typedef struct modulus_entry_t modulus_entry_t;
-
-/**
- * Entry of the modulus list.
- */
-struct modulus_entry_t {
- /**
- * Group number as it is defined in file transform_substructure.h.
- */
- diffie_hellman_group_t group;
-
- /**
- * Pointer to first byte of modulus (network order).
- */
- u_int8_t *modulus;
-
- /*
- * Length of modulus in bytes.
- */
- size_t modulus_len;
-
- /*
- * Generator value.
- */
- u_int16_t generator;
-};
-
-/**
- * All supported modulus values.
- */
-static modulus_entry_t modulus_entries[] = {
- {MODP_768_BIT, group1_modulus, sizeof(group1_modulus), 2},
- {MODP_1024_BIT, group2_modulus, sizeof(group2_modulus), 2},
- {MODP_1536_BIT, group5_modulus, sizeof(group5_modulus), 2},
- {MODP_2048_BIT, group14_modulus, sizeof(group14_modulus), 2},
- {MODP_3072_BIT, group15_modulus, sizeof(group15_modulus), 2},
- {MODP_4096_BIT, group16_modulus, sizeof(group16_modulus), 2},
- {MODP_6144_BIT, group17_modulus, sizeof(group17_modulus), 2},
- {MODP_8192_BIT, group18_modulus, sizeof(group18_modulus), 2},
-};
-
-typedef struct private_diffie_hellman_t private_diffie_hellman_t;
-
-/**
- * Private data of an diffie_hellman_t object.
- *
- */
-struct private_diffie_hellman_t {
- /**
- * Public diffie_hellman_t interface.
- */
- diffie_hellman_t public;
-
- /**
- * Diffie Hellman group number.
- */
- u_int16_t group;
-
- /*
- * Generator value.
- */
- mpz_t g;
-
- /**
- * My private value.
- */
- mpz_t xa;
-
- /**
- * My public value.
- */
- mpz_t ya;
-
- /**
- * Other public value.
- */
- mpz_t yb;
-
- /**
- * Shared secret.
- */
- mpz_t zz;
-
- /**
- * Modulus.
- */
- mpz_t p;
-
- /**
- * Modulus length.
- */
- size_t p_len;
-
- /**
- * True if shared secret is computed and stored in my_public_value.
- */
- bool computed;
-};
-
-/**
- * Implementation of diffie_hellman_t.set_other_public_value.
- */
-static void set_other_public_value(private_diffie_hellman_t *this, chunk_t value)
-{
- mpz_t p_min_1;
-
- mpz_init(p_min_1);
- mpz_sub_ui(p_min_1, this->p, 1);
-
- mpz_import(this->yb, value.len, 1, 1, 1, 0, value.ptr);
-
- /* check public value:
- * 1. 0 or 1 is invalid as 0^a = 0 and 1^a = 1
- * 2. a public value larger or equal the modulus is invalid */
- if (mpz_cmp_ui(this->yb, 1) > 0 ||
- mpz_cmp(this->yb, p_min_1) < 0)
- {
-#ifdef EXTENDED_DH_TEST
- /* 3. test if y ^ q mod p = 1, where q = (p - 1)/2. */
- mpz_t q, one;
-
- mpz_init(q);
- mpz_init(one);
- mpz_fdiv_q_2exp(q, p_min_1, 1);
- mpz_powm(one, this->yb, q, this->p);
- mpz_clear(q);
- if (mpz_cmp_ui(one, 1) == 0)
- {
- mpz_powm(this->zz, this->yb, this->xa, this->p);
- this->computed = TRUE;
- }
- else
- {
- DBG1("public DH value verification failed: y ^ q mod p != 1");
- }
- mpz_clear(one);
-#else
- mpz_powm(this->zz, this->yb, this->xa, this->p);
- this->computed = TRUE;
-#endif
- }
- else
- {
- DBG1("public DH value verification failed: y < 2 || y > p - 1 ");
- }
- mpz_clear(p_min_1);
-}
-
-/**
- * Implementation of diffie_hellman_t.get_other_public_value.
- */
-static status_t get_other_public_value(private_diffie_hellman_t *this,
- chunk_t *value)
-{
- if (!this->computed)
- {
- return FAILED;
- }
- value->len = this->p_len;
- value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->yb);
- return SUCCESS;
-}
-
-/**
- * Implementation of diffie_hellman_t.get_my_public_value.
- */
-static void get_my_public_value(private_diffie_hellman_t *this,chunk_t *value)
-{
- value->len = this->p_len;
- value->ptr = mpz_export(NULL, NULL, 1, value->len, 1, 0, this->ya);
-}
-
-/**
- * Implementation of diffie_hellman_t.get_shared_secret.
- */
-static status_t get_shared_secret(private_diffie_hellman_t *this, chunk_t *secret)
-{
- if (!this->computed)
- {
- return FAILED;
- }
- secret->len = this->p_len;
- secret->ptr = mpz_export(NULL, NULL, 1, secret->len, 1, 0, this->zz);
- return SUCCESS;
-}
-
-/**
- * Implementation of diffie_hellman_t.get_dh_group.
- */
-static diffie_hellman_group_t get_dh_group(private_diffie_hellman_t *this)
-{
- return this->group;
-}
-
-/**
- * Lookup the modulus in modulo table
- */
-static status_t set_modulus(private_diffie_hellman_t *this)
-{
- int i;
- status_t status = NOT_FOUND;
-
- for (i = 0; i < (sizeof(modulus_entries) / sizeof(modulus_entry_t)); i++)
- {
- if (modulus_entries[i].group == this->group)
- {
- chunk_t chunk;
- chunk.ptr = modulus_entries[i].modulus;
- chunk.len = modulus_entries[i].modulus_len;
- mpz_import(this->p, chunk.len, 1, 1, 1, 0, chunk.ptr);
- this->p_len = chunk.len;
- mpz_set_ui(this->g, modulus_entries[i].generator);
- status = SUCCESS;
- break;
- }
- }
- return status;
-}
-
-/**
- * Implementation of diffie_hellman_t.destroy.
- */
-static void destroy(private_diffie_hellman_t *this)
-{
- mpz_clear(this->p);
- mpz_clear(this->xa);
- mpz_clear(this->ya);
- mpz_clear(this->yb);
- mpz_clear(this->zz);
- mpz_clear(this->g);
- free(this);
-}
-
-/*
- * Described in header.
- */
-diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t group)
-{
- private_diffie_hellman_t *this = malloc_thing(private_diffie_hellman_t);
- randomizer_t *randomizer;
- chunk_t random;
- status_t status;
-
- /* public functions */
- this->public.get_shared_secret = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_shared_secret;
- this->public.set_other_public_value = (void (*)(diffie_hellman_t *, chunk_t )) set_other_public_value;
- this->public.get_other_public_value = (status_t (*)(diffie_hellman_t *, chunk_t *)) get_other_public_value;
- this->public.get_my_public_value = (void (*)(diffie_hellman_t *, chunk_t *)) get_my_public_value;
- this->public.get_dh_group = (diffie_hellman_group_t (*)(diffie_hellman_t *)) get_dh_group;
- this->public.destroy = (void (*)(diffie_hellman_t *)) destroy;
-
- /* private variables */
- this->group = group;
- mpz_init(this->p);
- mpz_init(this->yb);
- mpz_init(this->ya);
- mpz_init(this->xa);
- mpz_init(this->zz);
- mpz_init(this->g);
-
- this->computed = FALSE;
-
- /* find a modulus according to group */
- if (set_modulus(this) != SUCCESS)
- {
- destroy(this);
- return NULL;
- }
- randomizer = randomizer_create();
- status = randomizer->allocate_pseudo_random_bytes(
- randomizer, this->p_len, &random);
- randomizer->destroy(randomizer);
- if (status != SUCCESS)
- {
- destroy(this);
- return NULL;
- }
- mpz_import(this->xa, random.len, 1, 1, 1, 0, random.ptr);
- chunk_free(&random);
-
- mpz_powm(this->ya, this->g, this->xa, this->p);
-
- return &this->public;
-}
+ "MODP_8192_BIT",
+ "ECP_256_BIT",
+ "ECP_384_BIT",
+ "ECP_521_BIT");
+ENUM_NEXT(diffie_hellman_group_names, ECP_192_BIT, ECP_224_BIT, ECP_521_BIT,
+ "ECP_192_BIT",
+ "ECP_224_BIT");
+ENUM_END(diffie_hellman_group_names, ECP_224_BIT);
diff --git a/src/libstrongswan/crypto/diffie_hellman.h b/src/libstrongswan/crypto/diffie_hellman.h
index 8cd06d60e..c66ae56c3 100644
--- a/src/libstrongswan/crypto/diffie_hellman.h
+++ b/src/libstrongswan/crypto/diffie_hellman.h
@@ -1,10 +1,3 @@
-/**
- * @file diffie_hellman.h
- *
- * @brief Interface of diffie_hellman_t.
- *
- */
-
/*
* Copyright (C) 2005-2007 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* 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.
+ *
+ * $Id: diffie_hellman.h 4023 2008-05-29 06:55:03Z andreas $
+ */
+
+/**
+ * @defgroup diffie_hellman diffie_hellman
+ * @{ @ingroup crypto
*/
#ifndef DIFFIE_HELLMAN_H_
@@ -30,24 +30,28 @@ typedef struct diffie_hellman_t diffie_hellman_t;
#include <library.h>
/**
- * @brief Diffie-Hellman group.
+ * Diffie-Hellman group.
*
* The modulus (or group) to use for a Diffie-Hellman calculation.
- *
* See IKEv2 RFC 3.3.2 and RFC 3526.
- *
- * @ingroup crypto
+ *
+ * ECP groups are defined in RFC 4753 and RFC 5114.
*/
enum diffie_hellman_group_t {
- MODP_NONE = 0,
- MODP_768_BIT = 1,
- MODP_1024_BIT = 2,
- MODP_1536_BIT = 5,
+ MODP_NONE = 0,
+ MODP_768_BIT = 1,
+ MODP_1024_BIT = 2,
+ MODP_1536_BIT = 5,
MODP_2048_BIT = 14,
MODP_3072_BIT = 15,
MODP_4096_BIT = 16,
MODP_6144_BIT = 17,
- MODP_8192_BIT = 18
+ MODP_8192_BIT = 18,
+ ECP_256_BIT = 19,
+ ECP_384_BIT = 20,
+ ECP_521_BIT = 21,
+ ECP_192_BIT = 25,
+ ECP_224_BIT = 26,
};
/**
@@ -56,89 +60,60 @@ enum diffie_hellman_group_t {
extern enum_name_t *diffie_hellman_group_names;
/**
- * @brief Implementation of the Diffie-Hellman algorithm, as in RFC2631.
- *
- * @b Constructors:
- * - diffie_hellman_create()
- *
- * @ingroup crypto
+ * Implementation of the Diffie-Hellman algorithm, as in RFC2631.
*/
struct diffie_hellman_t {
/**
- * @brief Returns the shared secret of this diffie hellman exchange.
+ * Returns the shared secret of this diffie hellman exchange.
*
* Space for returned secret is allocated and must be
* freed by the caller.
*
- * @param this calling object
* @param secret shared secret will be written into this chunk
- * @return
- * - SUCCESS
- * - FAILED if not both DH values are set
+ * @return SUCCESS, FAILED if not both DH values are set
*/
status_t (*get_shared_secret) (diffie_hellman_t *this, chunk_t *secret);
/**
- * @brief Sets the public value of partner.
+ * Sets the public value of partner.
*
* Chunk gets cloned and can be destroyed afterwards.
*
- * @param this calling object
* @param value public value of partner
*/
void (*set_other_public_value) (diffie_hellman_t *this, chunk_t value);
/**
- * @brief Gets the public value of partner.
+ * Gets the public value of partner.
*
* Space for returned chunk is allocated and must be freed by the caller.
*
- * @param this calling object
* @param value public value of partner is stored at this location
- * @return
- * - SUCCESS
- * - FAILED if other public value not set
+ * @return SUCCESS, FAILED if other public value not set
*/
status_t (*get_other_public_value) (diffie_hellman_t *this, chunk_t *value);
/**
- * @brief Gets the own public value to transmit.
+ * Gets the own public value to transmit.
*
* Space for returned chunk is allocated and must be freed by the caller.
*
- * @param this calling object
* @param value public value of caller is stored at this location
*/
void (*get_my_public_value) (diffie_hellman_t *this, chunk_t *value);
/**
- * @brief Get the DH group used.
+ * Get the DH group used.
*
- * @param this calling object
* @return DH group set in construction
*/
diffie_hellman_group_t (*get_dh_group) (diffie_hellman_t *this);
/**
- * @brief Destroys an diffie_hellman_t object.
- *
- * @param this diffie_hellman_t object to destroy
+ * Destroys an diffie_hellman_t object.
*/
void (*destroy) (diffie_hellman_t *this);
};
-/**
- * @brief Creates a new diffie_hellman_t object.
- *
- * @param group Diffie Hellman group number to use
- * @return
- * - diffie_hellman_t object
- * - NULL if dh group not supported
- *
- * @ingroup crypto
- */
-diffie_hellman_t *diffie_hellman_create(diffie_hellman_group_t group);
-
-#endif /*DIFFIE_HELLMAN_H_*/
-
+#endif /*DIFFIE_HELLMAN_H_ @} */
diff --git a/src/libstrongswan/crypto/hashers/hasher.c b/src/libstrongswan/crypto/hashers/hasher.c
index 9fa778aa6..6c29d1d5d 100644
--- a/src/libstrongswan/crypto/hashers/hasher.c
+++ b/src/libstrongswan/crypto/hashers/hasher.c
@@ -1,10 +1,3 @@
-/**
- * @file hasher.c
- *
- * @brief Generic constructor for hasher_t.
- *
- */
-
/*
* Copyright (C) 2005 Jan Hutter
* Copyright (C) 2005-2006 Martin Willi
@@ -21,20 +14,16 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: hasher.c 3423 2008-01-22 10:32:37Z andreas $
+ * $Id: hasher.c 3619 2008-03-19 14:02:52Z martin $
*/
-
#include "hasher.h"
#include <asn1/oid.h>
-#include <crypto/hashers/sha1_hasher.h>
-#include <crypto/hashers/sha2_hasher.h>
-#include <crypto/hashers/md5_hasher.h>
-
ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512,
"HASH_UNKNOWN",
+ "HASH_PREFERRED",
"HASH_MD2",
"HASH_MD5",
"HASH_SHA1",
@@ -46,66 +35,31 @@ ENUM(hash_algorithm_names, HASH_UNKNOWN, HASH_SHA512,
/*
* Described in header.
*/
-hasher_t *hasher_create(hash_algorithm_t hash_algorithm)
-{
- switch (hash_algorithm)
- {
- case HASH_SHA1:
- {
- return (hasher_t*)sha1_hasher_create();
- }
- case HASH_SHA256:
- case HASH_SHA384:
- case HASH_SHA512:
- {
- return (hasher_t*)sha2_hasher_create(hash_algorithm);
- }
- case HASH_MD5:
- {
- return (hasher_t*)md5_hasher_create();
- }
- default:
- return NULL;
- }
-}
-
-/*
- * Described in header.
- */
hash_algorithm_t hasher_algorithm_from_oid(int oid)
{
- hash_algorithm_t algorithm;
-
switch (oid)
{
case OID_MD2:
case OID_MD2_WITH_RSA:
- algorithm = HASH_MD2;
- break;
+ return HASH_MD2;
case OID_MD5:
case OID_MD5_WITH_RSA:
- algorithm = HASH_MD5;
- break;
+ return HASH_MD5;
case OID_SHA1:
case OID_SHA1_WITH_RSA:
- algorithm = HASH_SHA1;
- break;
+ return HASH_SHA1;
case OID_SHA256:
case OID_SHA256_WITH_RSA:
- algorithm = HASH_SHA256;
- break;
+ return HASH_SHA256;
case OID_SHA384:
case OID_SHA384_WITH_RSA:
- algorithm = HASH_SHA384;
- break;
+ return HASH_SHA384;
case OID_SHA512:
case OID_SHA512_WITH_RSA:
- algorithm = HASH_SHA512;
- break;
+ return HASH_SHA512;
default:
- algorithm = HASH_UNKNOWN;
+ return HASH_UNKNOWN;
}
- return algorithm;
}
/*
diff --git a/src/libstrongswan/crypto/hashers/hasher.h b/src/libstrongswan/crypto/hashers/hasher.h
index e73de7f01..e19b0318b 100644
--- a/src/libstrongswan/crypto/hashers/hasher.h
+++ b/src/libstrongswan/crypto/hashers/hasher.h
@@ -1,10 +1,3 @@
-/**
- * @file hasher.h
- *
- * @brief Interface hasher_t.
- *
- */
-
/*
* Copyright (C) 2005 Jan Hutter
* Copyright (C) 2005-2006 Martin Willi
@@ -21,7 +14,12 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: hasher.h 3423 2008-01-22 10:32:37Z andreas $
+ * $Id: hasher.h 3619 2008-03-19 14:02:52Z martin $
+ */
+
+/**
+ * @defgroup traffic_selector traffic_selector
+ * @{ @ingroup config
*/
#ifndef HASHER_H_
@@ -33,30 +31,19 @@ typedef struct hasher_t hasher_t;
#include <library.h>
/**
- * @brief Algorithms to use for hashing.
- *
- * Currently only the following algorithms are implemented:
- * - HASH_MD5
- * - HASH_SHA1
- * - HASH_SHA256
- * - HASH_SHA384
- * - HASH_SHA512
- *
- * @ingroup hashers
+ * Algorithms to use for hashing.
*/
enum hash_algorithm_t {
- HASH_UNKNOWN = 0,
- HASH_MD2 = 1,
- /** Implemented in class md5_hasher_t */
- HASH_MD5 = 2,
- /** Implemented in class sha1_hasher_t */
- HASH_SHA1 = 3,
- /** Implemented in class sha2_hasher_t */
- HASH_SHA256 = 4,
- /** Implemented in class sha2_hasher_t */
- HASH_SHA384 = 5,
- /** Implemented in class sha2_hasher_t */
- HASH_SHA512 = 6,
+ /** not specified hash function */
+ HASH_UNKNOWN = 0,
+ /** preferred hash function, general purpose */
+ HASH_PREFERRED = 1,
+ HASH_MD2 = 2,
+ HASH_MD5 = 3,
+ HASH_SHA1 = 4,
+ HASH_SHA256 = 5,
+ HASH_SHA384 = 6,
+ HASH_SHA512 = 7,
};
#define HASH_SIZE_MD2 16
@@ -65,7 +52,6 @@ enum hash_algorithm_t {
#define HASH_SIZE_SHA256 32
#define HASH_SIZE_SHA384 48
#define HASH_SIZE_SHA512 64
-#define HASH_SIZE_MAX 64
/**
* enum names for hash_algorithm_t.
@@ -73,16 +59,11 @@ enum hash_algorithm_t {
extern enum_name_t *hash_algorithm_names;
/**
- * @brief Generic interface for all hash functions.
- *
- * @b Constructors:
- * - hasher_create()
- *
- * @ingroup hashers
+ * Generic interface for all hash functions.
*/
struct hasher_t {
/**
- * @brief Hash data and write it in the buffer.
+ * Hash data and write it in the buffer.
*
* If the parameter hash is NULL, no result is written back
* and more data can be appended to already hashed data.
@@ -91,108 +72,63 @@ struct hasher_t {
* The hash output parameter must hold at least
* hash_t.get_block_size() bytes.
*
- * @param this calling object
- * @param data data to hash
- * @param[out] hash pointer where the hash will be written
+ * @param data data to hash
+ * @param hash pointer where the hash will be written
*/
void (*get_hash) (hasher_t *this, chunk_t data, u_int8_t *hash);
/**
- * @brief Hash data and allocate space for the hash.
+ * Hash data and allocate space for the hash.
*
* If the parameter hash is NULL, no result is written back
* and more data can be appended to already hashed data.
* If not, the result is written back and the hasher is reset.
*
- * @param this calling object
- * @param data chunk with data to hash
- * @param[out] hash chunk which will hold allocated hash
+ * @param data chunk with data to hash
+ * @param hash chunk which will hold allocated hash
*/
void (*allocate_hash) (hasher_t *this, chunk_t data, chunk_t *hash);
/**
- * @brief Get the size of the resulting hash.
+ * Get the size of the resulting hash.
*
- * @param this calling object
- * @return hash size in bytes
+ * @return hash size in bytes
*/
size_t (*get_hash_size) (hasher_t *this);
/**
- * @brief Resets the hashers state.
- *
- * @param this calling object
+ * Resets the hashers state.
*/
void (*reset) (hasher_t *this);
/**
- * @brief Get the state of the hasher.
- *
- * A hasher stores internal state information. This state may be
- * manipulated to include a "seed" into the hashing operation. It used by
- * some exotic protocols (such as AKA).
- * The data pointed by chunk may be manipulated, but not replaced nor freed.
- * This is more a hack than a feature. The hasher's state may be byte
- * order dependant; use with care.
- *
- * @param this calling object
- */
- chunk_t (*get_state) (hasher_t *this);
-
- /**
- * @brief Destroys a hasher object.
- *
- * @param this calling object
+ * Destroys a hasher object.
*/
void (*destroy) (hasher_t *this);
};
/**
- * @brief Generic interface to create a hasher_t.
+ * Conversion of ASN.1 OID to hash algorithm.
*
- * @param hash_algorithm Algorithm to use for hashing
- * @return
- * - hasher_t object
- * - NULL if algorithm not supported
- *
- * @ingroup hashers
- */
-hasher_t *hasher_create(hash_algorithm_t hash_algorithm);
-
-/**
- * @brief Conversion of ASN.1 OID to hash algorithm.
- *
- * @param oid ASN.1 OID
- * @return
- * - hash algorithm
- * - HASH_UNKNOWN if OID unsuported
- *
- * @ingroup hashers
+ * @param oid ASN.1 OID
+ * @return hash algorithm, HASH_UNKNOWN if OID unsuported
*/
hash_algorithm_t hasher_algorithm_from_oid(int oid);
/**
- * @brief Conversion of hash algorithm into ASN.1 OID.
+ * Conversion of hash algorithm into ASN.1 OID.
*
- * @param alg hash algorithm
- * @return
- * - ASN.1 hash OID if known hash algorithm
- * - OID_UNKNOW
- *
- * @ingroup hashers
+ * @param alg hash algorithm
+ * @return ASN.1 OID, or OID_UNKNOW
*/
int hasher_algorithm_to_oid(hash_algorithm_t alg);
/**
- * @brief Conversion of hash signature algorithm into ASN.1 OID.
- *
- * @param alg hash algorithm
- * @return
- * - ASN.1 signature OID if known hash algorithm
- * - OID_UNKNOW
+ * Conversion of hash signature algorithm into ASN.1 OID.
*
- * @ingroup hashers
+ * @param alg hash algorithm
+ * @return ASN.1 OID if, or OID_UNKNOW
*/
int hasher_signature_algorithm_to_oid(hash_algorithm_t alg);
-#endif /* HASHER_H_ */
+#endif /* HASHER_H_ @} */
diff --git a/src/libstrongswan/crypto/hashers/md5_hasher.c b/src/libstrongswan/crypto/hashers/md5_hasher.c
deleted file mode 100644
index d4dde3693..000000000
--- a/src/libstrongswan/crypto/hashers/md5_hasher.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/**
- * @file md5_hasher.c
- *
- * @brief Implementation of md5_hasher_t.
- *
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- * Copyright (C) 1991-1992, RSA Data Security, Inc. Created 1991.
- * All rights reserved.
- *
- * Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm.
- * Ported to fulfill hasher_t interface.
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#include <string.h>
-
-#include "md5_hasher.h"
-
-
-/* Constants for MD5Transform routine. */
-#define S11 7
-#define S12 12
-#define S13 17
-#define S14 22
-#define S21 5
-#define S22 9
-#define S23 14
-#define S24 20
-#define S31 4
-#define S32 11
-#define S33 16
-#define S34 23
-#define S41 6
-#define S42 10
-#define S43 15
-#define S44 21
-
-static u_int8_t PADDING[64] = {
- 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-/*
- * ugly macro stuff
- */
-/* F, G, H and I are basic MD5 functions.
- */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define I(x, y, z) ((y) ^ ((x) | (~z)))
-
-/* ROTATE_LEFT rotates x left n bits.
- */
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-
-/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
-Rotation is separate from addition to prevent recomputation.
- */
-#define FF(a, b, c, d, x, s, ac) { \
- (a) += F ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define GG(a, b, c, d, x, s, ac) { \
- (a) += G ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define HH(a, b, c, d, x, s, ac) { \
- (a) += H ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-#define II(a, b, c, d, x, s, ac) { \
- (a) += I ((b), (c), (d)) + (x) + (u_int32_t)(ac); \
- (a) = ROTATE_LEFT ((a), (s)); \
- (a) += (b); \
- }
-
-
-
-typedef struct private_md5_hasher_t private_md5_hasher_t;
-
-/**
- * Private data structure with hasing context.
- */
-struct private_md5_hasher_t {
- /**
- * Public interface for this hasher.
- */
- md5_hasher_t public;
-
- /*
- * State of the hasher.
- */
- u_int32_t state[5];
- u_int32_t count[2];
- u_int8_t buffer[64];
-};
-
-
-#if BYTE_ORDER != LITTLE_ENDIAN
-
-/* Encodes input (u_int32_t) into output (u_int8_t). Assumes len is
- * a multiple of 4.
- */
-static void Encode (u_int8_t *output, u_int32_t *input, size_t len)
-{
- size_t i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4)
- {
- output[j] = (u_int8_t)(input[i] & 0xff);
- output[j+1] = (u_int8_t)((input[i] >> 8) & 0xff);
- output[j+2] = (u_int8_t)((input[i] >> 16) & 0xff);
- output[j+3] = (u_int8_t)((input[i] >> 24) & 0xff);
- }
-}
-
-/* Decodes input (u_int8_t) into output (u_int32_t). Assumes len is
- * a multiple of 4.
- */
-static void Decode(u_int32_t *output, u_int8_t *input, size_t len)
-{
- size_t i, j;
-
- for (i = 0, j = 0; j < len; i++, j += 4)
- {
- output[i] = ((u_int32_t)input[j]) | (((u_int32_t)input[j+1]) << 8) |
- (((u_int32_t)input[j+2]) << 16) | (((u_int32_t)input[j+3]) << 24);
- }
-}
-
-#elif BYTE_ORDER == LITTLE_ENDIAN
- #define Encode memcpy
- #define Decode memcpy
-#endif
-
-/* MD5 basic transformation. Transforms state based on block.
- */
-static void MD5Transform(u_int32_t state[4], u_int8_t block[64])
-{
- u_int32_t a = state[0], b = state[1], c = state[2], d = state[3], x[16];
-
- Decode(x, block, 64);
-
- /* Round 1 */
- FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
- FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
- FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
- FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
- FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
- FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
- FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
- FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
- FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
- FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
- FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
- FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
- FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
- FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
- FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
- FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
-
- /* Round 2 */
- GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
- GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
- GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
- GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
- GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
- GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
- GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
- GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
- GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
- GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
- GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
- GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
- GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
- GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
- GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
- GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
-
- /* Round 3 */
- HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
- HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
- HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
- HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
- HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
- HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
- HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
- HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
- HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
- HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
- HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
- HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
- HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
- HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
- HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
- HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
-
- /* Round 4 */
- II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
- II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
- II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
- II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
- II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
- II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
- II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
- II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
- II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
- II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
- II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
- II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
- II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
- II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
- II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
- II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
-
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
-}
-
-/* MD5 block update operation. Continues an MD5 message-digest
- * operation, processing another message block, and updating the
- * context.
- */
-static void MD5Update(private_md5_hasher_t *this, u_int8_t *input, size_t inputLen)
-{
- u_int32_t i;
- size_t index, partLen;
-
- /* Compute number of bytes mod 64 */
- index = (u_int8_t)((this->count[0] >> 3) & 0x3F);
-
- /* Update number of bits */
- if ((this->count[0] += (inputLen << 3)) < (inputLen << 3))
- {
- this->count[1]++;
- }
- this->count[1] += (inputLen >> 29);
-
- partLen = 64 - index;
-
- /* Transform as many times as possible. */
- if (inputLen >= partLen)
- {
- memcpy(&this->buffer[index], input, partLen);
- MD5Transform (this->state, this->buffer);
-
- for (i = partLen; i + 63 < inputLen; i += 64)
- {
- MD5Transform (this->state, &input[i]);
- }
- index = 0;
- }
- else
- {
- i = 0;
- }
-
- /* Buffer remaining input */
- memcpy(&this->buffer[index], &input[i], inputLen-i);
-}
-
-/* MD5 finalization. Ends an MD5 message-digest operation, writing the
- * the message digest and zeroizing the context.
- */
-static void MD5Final (private_md5_hasher_t *this, u_int8_t digest[16])
-{
- u_int8_t bits[8];
- size_t index, padLen;
-
- /* Save number of bits */
- Encode (bits, this->count, 8);
-
- /* Pad out to 56 mod 64. */
- index = (size_t)((this->count[0] >> 3) & 0x3f);
- padLen = (index < 56) ? (56 - index) : (120 - index);
- MD5Update (this, PADDING, padLen);
-
- /* Append length (before padding) */
- MD5Update (this, bits, 8);
-
- if (digest != NULL) /* Bill Simpson's padding */
- {
- /* store state in digest */
- Encode (digest, this->state, 16);
- }
-}
-
-
-
-/**
- * Implementation of hasher_t.get_hash.
- */
-static void get_hash(private_md5_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
-{
- MD5Update(this, chunk.ptr, chunk.len);
- if (buffer != NULL)
- {
- MD5Final(this, buffer);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
- }
-}
-
-
-/**
- * Implementation of hasher_t.allocate_hash.
- */
-static void allocate_hash(private_md5_hasher_t *this, chunk_t chunk, chunk_t *hash)
-{
- chunk_t allocated_hash;
-
- MD5Update(this, chunk.ptr, chunk.len);
- if (hash != NULL)
- {
- allocated_hash.ptr = malloc(HASH_SIZE_MD5);
- allocated_hash.len = HASH_SIZE_MD5;
-
- MD5Final(this, allocated_hash.ptr);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
-
- *hash = allocated_hash;
- }
-}
-
-/**
- * Implementation of hasher_t.get_hash_size.
- */
-static size_t get_hash_size(private_md5_hasher_t *this)
-{
- return HASH_SIZE_MD5;
-}
-
-/**
- * Implementation of hasher_t.reset.
- */
-static void reset(private_md5_hasher_t *this)
-{
- this->state[0] = 0x67452301;
- this->state[1] = 0xefcdab89;
- this->state[2] = 0x98badcfe;
- this->state[3] = 0x10325476;
- this->count[0] = 0;
- this->count[1] = 0;
-}
-
-/**
- * Implementation of hasher_t.get_state
- */
-static chunk_t get_state(private_md5_hasher_t *this)
-{
- chunk_t chunk;
-
- chunk.ptr = (u_char*)&this->state[0];
- chunk.len = sizeof(this->state);
-
- return chunk;
-}
-
-/**
- * Implementation of hasher_t.destroy.
- */
-static void destroy(private_md5_hasher_t *this)
-{
- free(this);
-}
-
-/*
- * Described in header.
- */
-md5_hasher_t *md5_hasher_create(void)
-{
- private_md5_hasher_t *this = malloc_thing(private_md5_hasher_t);
-
- this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
- this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
- this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
- this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
- this->public.hasher_interface.get_state = (chunk_t (*) (hasher_t*))get_state;
- this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
-
- /* initialize */
- reset(this);
-
- return &(this->public);
-}
diff --git a/src/libstrongswan/crypto/hashers/md5_hasher.h b/src/libstrongswan/crypto/hashers/md5_hasher.h
deleted file mode 100644
index 715f11663..000000000
--- a/src/libstrongswan/crypto/hashers/md5_hasher.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * @file md5_hasher.h
- *
- * @brief Interface for md5_hasher_t.
- *
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef MD5_HASHER_H_
-#define MD5_HASHER_H_
-
-typedef struct md5_hasher_t md5_hasher_t;
-
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief Implementation of hasher_t interface using the
- * MD5 algorithm.
- *
- * @b Constructors:
- * - hasher_create() using HASH_MD5 as algorithm
- * - md5_hasher_create()
- *
- * @see hasher_t
- *
- * @ingroup hashers
- */
-struct md5_hasher_t {
-
- /**
- * Generic hasher_t interface for this hasher.
- */
- hasher_t hasher_interface;
-};
-
-/**
- * @brief Creates a new md5_hasher_t.
- *
- * @return md5_hasher_t object
- *
- * @ingroup hashers
- */
-md5_hasher_t *md5_hasher_create(void);
-
-#endif /*MD5_HASHER_H_*/
diff --git a/src/libstrongswan/crypto/hashers/sha1_hasher.c b/src/libstrongswan/crypto/hashers/sha1_hasher.c
deleted file mode 100644
index 6a86937ae..000000000
--- a/src/libstrongswan/crypto/hashers/sha1_hasher.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/**
- * @file sha1_hasher.c
- *
- * @brief Implementation of hasher_sha_t.
- *
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * Ported from Steve Reid's <steve@edmweb.com> implementation
- * "SHA1 in C" found in strongSwan.
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#include <string.h>
-
-#include "sha1_hasher.h"
-
-/*
- * ugly macro stuff
- */
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-
-#if BYTE_ORDER == LITTLE_ENDIAN
- #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) |(rol(block->l[i],8)&0x00FF00FF))
-#elif BYTE_ORDER == BIG_ENDIAN
- #define blk0(i) block->l[i]
-#else
- #error "Endianness not defined!"
-#endif
-#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] ^block->l[(i+2)&15]^block->l[i&15],1))
-
-/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
-#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
-#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
-#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
-#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
-
-
-typedef struct private_sha1_hasher_t private_sha1_hasher_t;
-
-/**
- * Private data structure with hasing context.
- */
-struct private_sha1_hasher_t {
- /**
- * Public interface for this hasher.
- */
- sha1_hasher_t public;
-
- /*
- * State of the hasher.
- */
- u_int32_t state[5];
- u_int32_t count[2];
- u_int8_t buffer[64];
-};
-
-/*
- * Hash a single 512-bit block. This is the core of the algorithm. *
- */
-static void SHA1Transform(u_int32_t state[5], const unsigned char buffer[64])
-{
- u_int32_t a, b, c, d, e;
- typedef union {
- u_int8_t c[64];
- u_int32_t l[16];
- } CHAR64LONG16;
- CHAR64LONG16 block[1]; /* use array to appear as a pointer */
- memcpy(block, buffer, 64);
-
- /* Copy context->state[] to working vars */
- a = state[0];
- b = state[1];
- c = state[2];
- d = state[3];
- e = state[4];
- /* 4 rounds of 20 operations each. Loop unrolled. */
- R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
- R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
- R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
- R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
- R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
- R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
- R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
- R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
- R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
- R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
- R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
- R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
- R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
- R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
- R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
- R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
- R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
- R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
- R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
- R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
- /* Add the working vars back into context.state[] */
- state[0] += a;
- state[1] += b;
- state[2] += c;
- state[3] += d;
- state[4] += e;
- /* Wipe variables */
- a = b = c = d = e = 0;
- memset(block, '\0', sizeof(block));
-}
-
-/*
- * Run your data through this.
- */
-static void SHA1Update(private_sha1_hasher_t* this, u_int8_t *data, u_int32_t len)
-{
- u_int32_t i;
- u_int32_t j;
-
- j = this->count[0];
- if ((this->count[0] += len << 3) < j)
- {
- this->count[1]++;
- }
- this->count[1] += (len>>29);
- j = (j >> 3) & 63;
- if ((j + len) > 63)
- {
- memcpy(&this->buffer[j], data, (i = 64-j));
- SHA1Transform(this->state, this->buffer);
- for ( ; i + 63 < len; i += 64)
- {
- SHA1Transform(this->state, &data[i]);
- }
- j = 0;
- }
- else
- {
- i = 0;
- }
- memcpy(&this->buffer[j], &data[i], len - i);
-}
-
-
-/*
- * Add padding and return the message digest.
- */
-static void SHA1Final(private_sha1_hasher_t *this, u_int8_t *digest)
-{
- u_int32_t i;
- u_int8_t finalcount[8];
- u_int8_t c;
-
- for (i = 0; i < 8; i++)
- {
- finalcount[i] = (u_int8_t)((this->count[(i >= 4 ? 0 : 1)]
- >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
- }
- c = 0200;
- SHA1Update(this, &c, 1);
- while ((this->count[0] & 504) != 448)
- {
- c = 0000;
- SHA1Update(this, &c, 1);
- }
- SHA1Update(this, finalcount, 8); /* Should cause a SHA1Transform() */
- for (i = 0; i < 20; i++)
- {
- digest[i] = (u_int8_t)((this->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
- }
-}
-
-
-/**
- * Implementation of hasher_t.get_hash.
- */
-static void get_hash(private_sha1_hasher_t *this, chunk_t chunk, u_int8_t *buffer)
-{
- SHA1Update(this, chunk.ptr, chunk.len);
- if (buffer != NULL)
- {
- SHA1Final(this, buffer);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
- }
-}
-
-
-/**
- * Implementation of hasher_t.allocate_hash.
- */
-static void allocate_hash(private_sha1_hasher_t *this, chunk_t chunk, chunk_t *hash)
-{
- chunk_t allocated_hash;
-
- SHA1Update(this, chunk.ptr, chunk.len);
- if (hash != NULL)
- {
- allocated_hash.ptr = malloc(HASH_SIZE_SHA1);
- allocated_hash.len = HASH_SIZE_SHA1;
-
- SHA1Final(this, allocated_hash.ptr);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
-
- *hash = allocated_hash;
- }
-}
-
-/**
- * Implementation of hasher_t.get_hash_size.
- */
-static size_t get_hash_size(private_sha1_hasher_t *this)
-{
- return HASH_SIZE_SHA1;
-}
-
-/**
- * Implementation of hasher_t.reset.
- */
-static void reset(private_sha1_hasher_t *this)
-{
- this->state[0] = 0x67452301;
- this->state[1] = 0xEFCDAB89;
- this->state[2] = 0x98BADCFE;
- this->state[3] = 0x10325476;
- this->state[4] = 0xC3D2E1F0;
- this->count[0] = 0;
- this->count[1] = 0;
-}
-
-/**
- * Implementation of hasher_t.get_state
- */
-static chunk_t get_state(private_sha1_hasher_t *this)
-{
- chunk_t chunk;
-
- chunk.ptr = (u_char*)&this->state[0];
- chunk.len = sizeof(this->state);
-
- return chunk;
-}
-
-/**
- * Implementation of hasher_t.destroy.
- */
-static void destroy(private_sha1_hasher_t *this)
-{
- free(this);
-}
-
-/*
- * Described in header.
- */
-sha1_hasher_t *sha1_hasher_create(void)
-{
- private_sha1_hasher_t *this = malloc_thing(private_sha1_hasher_t);
-
- this->public.hasher_interface.get_hash = (void (*) (hasher_t*, chunk_t, u_int8_t*))get_hash;
- this->public.hasher_interface.allocate_hash = (void (*) (hasher_t*, chunk_t, chunk_t*))allocate_hash;
- this->public.hasher_interface.get_hash_size = (size_t (*) (hasher_t*))get_hash_size;
- this->public.hasher_interface.reset = (void (*) (hasher_t*))reset;
- this->public.hasher_interface.get_state = (chunk_t (*) (hasher_t*))get_state;
- this->public.hasher_interface.destroy = (void (*) (hasher_t*))destroy;
-
- /* initialize */
- reset(this);
-
- return &(this->public);
-}
diff --git a/src/libstrongswan/crypto/hashers/sha1_hasher.h b/src/libstrongswan/crypto/hashers/sha1_hasher.h
deleted file mode 100644
index 380fa9845..000000000
--- a/src/libstrongswan/crypto/hashers/sha1_hasher.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * @file sha1_hasher.h
- *
- * @brief Interface of sha1_hasher_t
- *
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef SHA1_HASHER_H_
-#define SHA1_HASHER_H_
-
-typedef struct sha1_hasher_t sha1_hasher_t;
-
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief Implementation of hasher_t interface using the
- * SHA1 algorithm.
- *
- * @b Constructors:
- * - hasher_create() using HASH_SHA1 as algorithm
- * - sha1_hasher_create()
- *
- * @see hasher_t
- *
- * @ingroup hashers
- */
-struct sha1_hasher_t {
-
- /**
- * Generic hasher_t interface for this hasher.
- */
- hasher_t hasher_interface;
-};
-
-/**
- * @brief Creates a new sha1_hasher_t.
- *
- * @return sha1_hasher_t object
- *
- * @ingroup hashers
- */
-sha1_hasher_t *sha1_hasher_create(void);
-
-#endif /*SHA1_HASHER_H_*/
diff --git a/src/libstrongswan/crypto/hashers/sha2_hasher.c b/src/libstrongswan/crypto/hashers/sha2_hasher.c
deleted file mode 100644
index b68972cec..000000000
--- a/src/libstrongswan/crypto/hashers/sha2_hasher.c
+++ /dev/null
@@ -1,672 +0,0 @@
-/**
- * @file sha2_hasher.c
- *
- * @brief Implementation of hasher_sha_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Martin Willi
- * Hochschule fuer Technik Rapperswil
- * Copyright (C) 2001 Jari Ruusu.
- *
- * Ported from strongSwans implementation written by Jari Ruusu.
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#include <string.h>
-
-#include "sha2_hasher.h"
-
-
-typedef struct private_sha512_hasher_t private_sha512_hasher_t;
-
-/**
- * Private data structure with hasing context for SHA384 and SHA512
- */
-struct private_sha512_hasher_t {
- /**
- * Public interface for this hasher.
- */
- sha2_hasher_t public;
-
- unsigned char sha_out[128]; /* results are here, bytes 0..47/0..63 */
- u_int64_t sha_H[8];
- u_int64_t sha_blocks;
- u_int64_t sha_blocksMSB;
- int sha_bufCnt;
-};
-
-
-typedef struct private_sha256_hasher_t private_sha256_hasher_t;
-
-/**
- * Private data structure with hasing context for SHA256
- */
-struct private_sha256_hasher_t {
- /**
- * Public interface for this hasher.
- */
- sha2_hasher_t public;
-
- unsigned char sha_out[64]; /* results are here, bytes 0...31 */
- u_int32_t sha_H[8];
- u_int64_t sha_blocks;
- int sha_bufCnt;
-};
-
-
-static const u_int32_t sha256_hashInit[8] = {
- 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c,
- 0x1f83d9ab, 0x5be0cd19
-};
-
-static const u_int32_t sha256_K[64] = {
- 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1,
- 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786,
- 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
- 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
- 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
- 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
- 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
- 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a,
- 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
- 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-};
-
-static const u_int64_t sha512_hashInit[8] = {
- 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL,
- 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
- 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
-};
-
-static const u_int64_t sha384_hashInit[8] = {
- 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL,
- 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL,
- 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
-};
-
-static const u_int64_t sha512_K[80] = {
- 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL,
- 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL,
- 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL,
- 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
- 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL,
- 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL,
- 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL,
- 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
- 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL,
- 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL,
- 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL,
- 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
- 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL,
- 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL,
- 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL,
- 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
- 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL,
- 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL,
- 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL,
- 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
- 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL,
- 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL,
- 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL,
- 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
- 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL,
- 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL,
- 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
-};
-
-
-/* set macros for SHA256 */
-#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
-#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
-#define R(x,y) ((y) >> (x))
-
-#define S(x,y) (((y) >> (x)) | ((y) << (32 - (x))))
-#define uSig0(x) ((S(2,(x))) ^ (S(13,(x))) ^ (S(22,(x))))
-#define uSig1(x) ((S(6,(x))) ^ (S(11,(x))) ^ (S(25,(x))))
-#define lSig0(x) ((S(7,(x))) ^ (S(18,(x))) ^ (R(3,(x))))
-#define lSig1(x) ((S(17,(x))) ^ (S(19,(x))) ^ (R(10,(x))))
-
-/**
- * Single block SHA256 transformation
- */
-static void sha256_transform(private_sha256_hasher_t *ctx,
- const unsigned char *datap)
-{
- register int j;
- u_int32_t a, b, c, d, e, f, g, h;
- u_int32_t T1, T2, W[64], Wm2, Wm15;
-
- /* read the data, big endian byte order */
- j = 0;
- do {
- W[j] = (((u_int32_t)(datap[0]))<<24) | (((u_int32_t)(datap[1]))<<16) |
- (((u_int32_t)(datap[2]))<<8 ) | ((u_int32_t)(datap[3]));
- datap += 4;
- } while(++j < 16);
-
- /* initialize variables a...h */
- a = ctx->sha_H[0];
- b = ctx->sha_H[1];
- c = ctx->sha_H[2];
- d = ctx->sha_H[3];
- e = ctx->sha_H[4];
- f = ctx->sha_H[5];
- g = ctx->sha_H[6];
- h = ctx->sha_H[7];
-
- /* apply compression function */
- j = 0;
- do
- {
- if(j >= 16)
- {
- Wm2 = W[j - 2];
- Wm15 = W[j - 15];
- W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
- }
- T1 = h + uSig1(e) + Ch(e,f,g) + sha256_K[j] + W[j];
- T2 = uSig0(a) + Maj(a,b,c);
- h = g; g = f; f = e;
- e = d + T1;
- d = c; c = b; b = a;
- a = T1 + T2;
- } while(++j < 64);
-
- /* compute intermediate hash value */
- ctx->sha_H[0] += a;
- ctx->sha_H[1] += b;
- ctx->sha_H[2] += c;
- ctx->sha_H[3] += d;
- ctx->sha_H[4] += e;
- ctx->sha_H[5] += f;
- ctx->sha_H[6] += g;
- ctx->sha_H[7] += h;
-
- ctx->sha_blocks++;
-}
-
-/**
- * Update SHA256 hash
- */
-static void sha256_write(private_sha256_hasher_t *ctx,
- const unsigned char *datap, int length)
-{
- while(length > 0)
- {
- if(!ctx->sha_bufCnt)
- {
- while(length >= sizeof(ctx->sha_out))
- {
- sha256_transform(ctx, datap);
- datap += sizeof(ctx->sha_out);
- length -= sizeof(ctx->sha_out);
- }
- if(!length) return;
- }
- ctx->sha_out[ctx->sha_bufCnt] = *datap++;
- length--;
- if(++ctx->sha_bufCnt == sizeof(ctx->sha_out))
- {
- sha256_transform(ctx, &ctx->sha_out[0]);
- ctx->sha_bufCnt = 0;
- }
- }
-}
-
-/**
- * finalize SHA256 hash
- */
-static void sha256_final(private_sha256_hasher_t *ctx)
-{
- register int j;
- u_int64_t bitLength;
- u_int32_t i;
- unsigned char padByte, *datap;
-
- bitLength = (ctx->sha_blocks << 9) | (ctx->sha_bufCnt << 3);
- padByte = 0x80;
- sha256_write(ctx, &padByte, 1);
-
- /* pad extra space with zeroes */
- padByte = 0;
- while(ctx->sha_bufCnt != 56)
- {
- sha256_write(ctx, &padByte, 1);
- }
-
- /* write bit length, big endian byte order */
- ctx->sha_out[56] = bitLength >> 56;
- ctx->sha_out[57] = bitLength >> 48;
- ctx->sha_out[58] = bitLength >> 40;
- ctx->sha_out[59] = bitLength >> 32;
- ctx->sha_out[60] = bitLength >> 24;
- ctx->sha_out[61] = bitLength >> 16;
- ctx->sha_out[62] = bitLength >> 8;
- ctx->sha_out[63] = bitLength;
- sha256_transform(ctx, &ctx->sha_out[0]);
-
- /* return results in ctx->sha_out[0...31] */
- datap = &ctx->sha_out[0];
- j = 0;
- do {
- i = ctx->sha_H[j];
- datap[0] = i >> 24;
- datap[1] = i >> 16;
- datap[2] = i >> 8;
- datap[3] = i;
- datap += 4;
- } while(++j < 8);
-}
-
-/* update macros for SHA512 */
-#undef S
-#undef uSig0
-#undef uSig1
-#undef lSig0
-#undef lSig1
-#define S(x,y) (((y) >> (x)) | ((y) << (64 - (x))))
-#define uSig0(x) ((S(28,(x))) ^ (S(34,(x))) ^ (S(39,(x))))
-#define uSig1(x) ((S(14,(x))) ^ (S(18,(x))) ^ (S(41,(x))))
-#define lSig0(x) ((S(1,(x))) ^ (S(8,(x))) ^ (R(7,(x))))
-#define lSig1(x) ((S(19,(x))) ^ (S(61,(x))) ^ (R(6,(x))))
-
-/**
- * Single block SHA384/SHA512 transformation
- */
-static void sha512_transform(private_sha512_hasher_t *ctx,
- const unsigned char *datap)
-{
- register int j;
- u_int64_t a, b, c, d, e, f, g, h;
- u_int64_t T1, T2, W[80], Wm2, Wm15;
-
- /* read the data, big endian byte order */
- j = 0;
- do {
- W[j] = (((u_int64_t)(datap[0]))<<56) | (((u_int64_t)(datap[1]))<<48) |
- (((u_int64_t)(datap[2]))<<40) | (((u_int64_t)(datap[3]))<<32) |
- (((u_int64_t)(datap[4]))<<24) | (((u_int64_t)(datap[5]))<<16) |
- (((u_int64_t)(datap[6]))<<8 ) | ((u_int64_t)(datap[7]));
- datap += 8;
- } while(++j < 16);
-
- /* initialize variables a...h */
- a = ctx->sha_H[0];
- b = ctx->sha_H[1];
- c = ctx->sha_H[2];
- d = ctx->sha_H[3];
- e = ctx->sha_H[4];
- f = ctx->sha_H[5];
- g = ctx->sha_H[6];
- h = ctx->sha_H[7];
-
- /* apply compression function */
- j = 0;
- do {
- if(j >= 16) {
- Wm2 = W[j - 2];
- Wm15 = W[j - 15];
- W[j] = lSig1(Wm2) + W[j - 7] + lSig0(Wm15) + W[j - 16];
- }
- T1 = h + uSig1(e) + Ch(e,f,g) + sha512_K[j] + W[j];
- T2 = uSig0(a) + Maj(a,b,c);
- h = g; g = f; f = e;
- e = d + T1;
- d = c; c = b; b = a;
- a = T1 + T2;
- } while(++j < 80);
-
- /* compute intermediate hash value */
- ctx->sha_H[0] += a;
- ctx->sha_H[1] += b;
- ctx->sha_H[2] += c;
- ctx->sha_H[3] += d;
- ctx->sha_H[4] += e;
- ctx->sha_H[5] += f;
- ctx->sha_H[6] += g;
- ctx->sha_H[7] += h;
-
- ctx->sha_blocks++;
- if(!ctx->sha_blocks) ctx->sha_blocksMSB++;
-}
-
-/**
- * Update a SHA384/SHA512 hash
- */
-static void sha512_write(private_sha512_hasher_t *ctx,
- const unsigned char *datap, int length)
-{
- while(length > 0)
- {
- if(!ctx->sha_bufCnt)
- {
- while(length >= sizeof(ctx->sha_out))
- {
- sha512_transform(ctx, datap);
- datap += sizeof(ctx->sha_out);
- length -= sizeof(ctx->sha_out);
- }
- if(!length) return;
- }
- ctx->sha_out[ctx->sha_bufCnt] = *datap++;
- length--;
- if(++ctx->sha_bufCnt == sizeof(ctx->sha_out))
- {
- sha512_transform(ctx, &ctx->sha_out[0]);
- ctx->sha_bufCnt = 0;
- }
- }
-}
-
-/**
- * Finalize a SHA384/SHA512 hash
- */
-static void sha512_final(private_sha512_hasher_t *ctx)
-{
- register int j;
- u_int64_t bitLength, bitLengthMSB;
- u_int64_t i;
- unsigned char padByte, *datap;
-
- bitLength = (ctx->sha_blocks << 10) | (ctx->sha_bufCnt << 3);
- bitLengthMSB = (ctx->sha_blocksMSB << 10) | (ctx->sha_blocks >> 54);
- padByte = 0x80;
- sha512_write(ctx, &padByte, 1);
-
- /* pad extra space with zeroes */
- padByte = 0;
- while(ctx->sha_bufCnt != 112)
- {
- sha512_write(ctx, &padByte, 1);
- }
-
- /* write bit length, big endian byte order */
- ctx->sha_out[112] = bitLengthMSB >> 56;
- ctx->sha_out[113] = bitLengthMSB >> 48;
- ctx->sha_out[114] = bitLengthMSB >> 40;
- ctx->sha_out[115] = bitLengthMSB >> 32;
- ctx->sha_out[116] = bitLengthMSB >> 24;
- ctx->sha_out[117] = bitLengthMSB >> 16;
- ctx->sha_out[118] = bitLengthMSB >> 8;
- ctx->sha_out[119] = bitLengthMSB;
- ctx->sha_out[120] = bitLength >> 56;
- ctx->sha_out[121] = bitLength >> 48;
- ctx->sha_out[122] = bitLength >> 40;
- ctx->sha_out[123] = bitLength >> 32;
- ctx->sha_out[124] = bitLength >> 24;
- ctx->sha_out[125] = bitLength >> 16;
- ctx->sha_out[126] = bitLength >> 8;
- ctx->sha_out[127] = bitLength;
- sha512_transform(ctx, &ctx->sha_out[0]);
-
- /* return results in ctx->sha_out[0...63] */
- datap = &ctx->sha_out[0];
- j = 0;
- do {
- i = ctx->sha_H[j];
- datap[0] = i >> 56;
- datap[1] = i >> 48;
- datap[2] = i >> 40;
- datap[3] = i >> 32;
- datap[4] = i >> 24;
- datap[5] = i >> 16;
- datap[6] = i >> 8;
- datap[7] = i;
- datap += 8;
- } while(++j < 8);
-}
-
-/**
- * Implementation of hasher_t.get_hash for SHA256.
- */
-static void get_hash256(private_sha256_hasher_t *this,
- chunk_t chunk, u_int8_t *buffer)
-{
- sha256_write(this, chunk.ptr, chunk.len);
- if (buffer != NULL)
- {
- sha256_final(this);
- memcpy(buffer, this->sha_out, HASH_SIZE_SHA256);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
- }
-}
-
-/**
- * Implementation of hasher_t.get_hash for SHA384.
- */
-static void get_hash384(private_sha512_hasher_t *this,
- chunk_t chunk, u_int8_t *buffer)
-{
- sha512_write(this, chunk.ptr, chunk.len);
- if (buffer != NULL)
- {
- sha512_final(this);
- memcpy(buffer, this->sha_out, HASH_SIZE_SHA384);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
- }
-}
-
-/**
- * Implementation of hasher_t.get_hash for SHA512.
- */
-static void get_hash512(private_sha512_hasher_t *this,
- chunk_t chunk, u_int8_t *buffer)
-{
- sha512_write(this, chunk.ptr, chunk.len);
- if (buffer != NULL)
- {
- sha512_final(this);
- memcpy(buffer, this->sha_out, HASH_SIZE_SHA512);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
- }
-}
-
-/**
- * Implementation of hasher_t.allocate_hash for SHA256.
- */
-static void allocate_hash256(private_sha256_hasher_t *this,
- chunk_t chunk, chunk_t *hash)
-{
- chunk_t allocated_hash;
-
- sha256_write(this, chunk.ptr, chunk.len);
- if (hash != NULL)
- {
- sha256_final(this);
- allocated_hash = chunk_alloc(HASH_SIZE_SHA256);
- memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA256);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
- *hash = allocated_hash;
- }
-}
-
-/**
- * Implementation of hasher_t.allocate_hash for SHA384.
- */
-static void allocate_hash384(private_sha512_hasher_t *this,
- chunk_t chunk, chunk_t *hash)
-{
- chunk_t allocated_hash;
-
- sha512_write(this, chunk.ptr, chunk.len);
- if (hash != NULL)
- {
- sha512_final(this);
- allocated_hash = chunk_alloc(HASH_SIZE_SHA384);
- memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA384);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
- *hash = allocated_hash;
- }
-}
-
-/**
- * Implementation of hasher_t.allocate_hash for SHA512.
- */
-static void allocate_hash512(private_sha512_hasher_t *this,
- chunk_t chunk, chunk_t *hash)
-{
- chunk_t allocated_hash;
-
- sha512_write(this, chunk.ptr, chunk.len);
- if (hash != NULL)
- {
- sha512_final(this);
- allocated_hash = chunk_alloc(HASH_SIZE_SHA512);
- memcpy(allocated_hash.ptr, this->sha_out, HASH_SIZE_SHA512);
- this->public.hasher_interface.reset(&(this->public.hasher_interface));
- *hash = allocated_hash;
- }
-}
-
-/**
- * Implementation of hasher_t.get_hash_size for SHA256.
- */
-static size_t get_hash_size256(private_sha256_hasher_t *this)
-{
- return HASH_SIZE_SHA256;
-}
-
-/**
- * Implementation of hasher_t.get_hash_size for SHA384.
- */
-static size_t get_hash_size384(private_sha512_hasher_t *this)
-{
- return HASH_SIZE_SHA384;
-}
-
-/**
- * Implementation of hasher_t.get_hash_size for SHA512.
- */
-static size_t get_hash_size512(private_sha512_hasher_t *this)
-{
- return HASH_SIZE_SHA512;
-}
-
-/**
- * Implementation of hasher_t.reset for SHA256
- */
-static void reset256(private_sha256_hasher_t *ctx)
-{
- memcpy(&ctx->sha_H[0], &sha256_hashInit[0], sizeof(ctx->sha_H));
- ctx->sha_blocks = 0;
- ctx->sha_bufCnt = 0;
-}
-
-/**
- * Implementation of hasher_t.reset for SHA384
- */
-static void reset384(private_sha512_hasher_t *ctx)
-{
- memcpy(&ctx->sha_H[0], &sha384_hashInit[0], sizeof(ctx->sha_H));
- ctx->sha_blocks = 0;
- ctx->sha_blocksMSB = 0;
- ctx->sha_bufCnt = 0;
-}
-
-/**
- * Implementation of hasher_t.reset for SHA512
- */
-static void reset512(private_sha512_hasher_t *ctx)
-{
- memcpy(&ctx->sha_H[0], &sha512_hashInit[0], sizeof(ctx->sha_H));
- ctx->sha_blocks = 0;
- ctx->sha_blocksMSB = 0;
- ctx->sha_bufCnt = 0;
-}
-
-/**
- * Implementation of hasher_t.get_state for SHA256
- */
-static chunk_t get_state256(private_sha256_hasher_t *ctx)
-{
- chunk_t chunk;
- chunk.ptr = (u_char*)&ctx->sha_H[0];
- chunk.len = HASH_SIZE_SHA256;
- return chunk;
-}
-
-/**
- * Implementation of hasher_t.get_state for SHA384
- */
-static chunk_t get_state384(private_sha512_hasher_t *ctx)
-{
- chunk_t chunk;
- chunk.ptr = (u_char*)&ctx->sha_H[0];
- chunk.len = HASH_SIZE_SHA384;
- return chunk;
-}
-/**
- * Implementation of hasher_t.get_state for SHA512
- */
-static chunk_t get_state512(private_sha512_hasher_t *ctx)
-{
- chunk_t chunk;
- chunk.ptr = (u_char*)&ctx->sha_H[0];
- chunk.len = HASH_SIZE_SHA512;
- return chunk;
-}
-
-/**
- * Implementation of hasher_t.destroy.
- */
-static void destroy(sha2_hasher_t *this)
-{
- free(this);
-}
-
-/*
- * Described in header.
- */
-sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm)
-{
- sha2_hasher_t *this;
-
- switch (algorithm)
- {
- case HASH_SHA256:
- this = (sha2_hasher_t*)malloc_thing(private_sha256_hasher_t);
- this->hasher_interface.reset = (void(*)(hasher_t*))reset256;
- this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state256;
- this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size256;
- this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash256;
- this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash256;
- break;
- case HASH_SHA384:
- /* uses SHA512 data structure */
- this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
- this->hasher_interface.reset = (void(*)(hasher_t*))reset384;
- this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state384;
- this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size384;
- this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash384;
- this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash384;
- break;
- case HASH_SHA512:
- this = (sha2_hasher_t*)malloc_thing(private_sha512_hasher_t);
- this->hasher_interface.reset = (void(*)(hasher_t*))reset512;
- this->hasher_interface.get_state = (chunk_t(*)(hasher_t*))get_state512;
- this->hasher_interface.get_hash_size = (size_t(*)(hasher_t*))get_hash_size512;
- this->hasher_interface.get_hash = (void(*)(hasher_t*,chunk_t,u_int8_t*))get_hash512;
- this->hasher_interface.allocate_hash = (void(*)(hasher_t*,chunk_t,chunk_t*))allocate_hash512;
- break;
- default:
- return NULL;
- }
- this->hasher_interface.destroy = (void(*)(hasher_t*))destroy;
-
- /* initialize */
- this->hasher_interface.reset(&this->hasher_interface);
-
- return this;
-}
diff --git a/src/libstrongswan/crypto/hashers/sha2_hasher.h b/src/libstrongswan/crypto/hashers/sha2_hasher.h
deleted file mode 100644
index 91e82fedb..000000000
--- a/src/libstrongswan/crypto/hashers/sha2_hasher.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file sha2_hasher.h
- *
- * @brief Interface of sha2_hasher_t
- *
- */
-
-/*
- * Copyright (C) 2006 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef SHA2_HASHER_H_
-#define SHA2_HASHER_H_
-
-typedef struct sha2_hasher_t sha2_hasher_t;
-
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief Implementation of hasher_t interface using the SHA2 algorithms.
- *
- * SHA2 is an other name for the SHA-256, SHA-384 and SHA-512 variants of
- * the SHA hash algorithm.
- *
- * @b Constructors:
- * - hasher_create() using HASH_SHA256, HASH_SHA384 or HASH_SHA512 as algorithm
- * - sha2_hasher_create()
- *
- * @see hasher_t
- *
- * @ingroup hashers
- */
-struct sha2_hasher_t {
-
- /**
- * Generic hasher_t interface for this hasher.
- */
- hasher_t hasher_interface;
-};
-
-/**
- * @brief Creates a new sha2_hasher_t.
- *
- * @param algorithm HASH_SHA256, HASH_SHA384 or HASH_SHA512
- * @return sha2_hasher_t object
- *
- * @ingroup hashers
- */
-sha2_hasher_t *sha2_hasher_create(hash_algorithm_t algorithm);
-
-#endif /* SHA2_HASHER_H_ */
diff --git a/src/libstrongswan/crypto/hmac.c b/src/libstrongswan/crypto/hmac.c
deleted file mode 100644
index df4f90bc8..000000000
--- a/src/libstrongswan/crypto/hmac.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/**
- * @file hmac.c
- *
- * @brief Implementation of hmac_t.
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General hmac License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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 hmac License
- * for more details.
- */
-
-#include <string.h>
-
-#include "hmac.h"
-
-
-typedef struct private_hmac_t private_hmac_t;
-
-/**
- * Private data of a hmac_t object.
- *
- * The variable names are the same as in the RFC.
- */
-struct private_hmac_t {
- /**
- * Public hmac_t interface.
- */
- hmac_t hmac;
-
- /**
- * Block size, as in RFC.
- */
- u_int8_t b;
-
- /**
- * Hash function.
- */
- hasher_t *h;
-
- /**
- * Previously xor'ed key using opad.
- */
- chunk_t opaded_key;
-
- /**
- * Previously xor'ed key using ipad.
- */
- chunk_t ipaded_key;
-};
-
-/**
- * Implementation of hmac_t.get_mac.
- */
-static void get_mac(private_hmac_t *this, chunk_t data, u_int8_t *out)
-{
- /* H(K XOR opad, H(K XOR ipad, text))
- *
- * if out is NULL, we append text to the inner hash.
- * else, we complete the inner and do the outer.
- *
- */
-
- u_int8_t buffer[this->h->get_hash_size(this->h)];
- chunk_t inner;
-
- if (out == NULL)
- {
- /* append data to inner */
- this->h->get_hash(this->h, data, NULL);
- }
- else
- {
- /* append and do outer hash */
- inner.ptr = buffer;
- inner.len = this->h->get_hash_size(this->h);
-
- /* complete inner */
- this->h->get_hash(this->h, data, buffer);
-
- /* do outer */
- this->h->get_hash(this->h, this->opaded_key, NULL);
- this->h->get_hash(this->h, inner, out);
-
- /* reinit for next call */
- this->h->get_hash(this->h, this->ipaded_key, NULL);
- }
-}
-
-/**
- * Implementation of hmac_t.allocate_mac.
- */
-static void allocate_mac(private_hmac_t *this, chunk_t data, chunk_t *out)
-{
- /* allocate space and use get_mac */
- if (out == NULL)
- {
- /* append mode */
- this->hmac.get_mac(&(this->hmac), data, NULL);
- }
- else
- {
- out->len = this->h->get_hash_size(this->h);
- out->ptr = malloc(out->len);
- this->hmac.get_mac(&(this->hmac), data, out->ptr);
- }
-}
-
-/**
- * Implementation of hmac_t.get_block_size.
- */
-static size_t get_block_size(private_hmac_t *this)
-{
- return this->h->get_hash_size(this->h);
-}
-
-/**
- * Implementation of hmac_t.set_key.
- */
-static void set_key(private_hmac_t *this, chunk_t key)
-{
- int i;
- u_int8_t buffer[this->b];
-
- memset(buffer, 0, this->b);
-
- if (key.len > this->b)
- {
- /* if key is too long, it will be hashed */
- this->h->get_hash(this->h, key, buffer);
- }
- else
- {
- /* if not, just copy it in our pre-padded k */
- memcpy(buffer, key.ptr, key.len);
- }
-
- /* apply ipad and opad to key */
- for (i = 0; i < this->b; i++)
- {
- this->ipaded_key.ptr[i] = buffer[i] ^ 0x36;
- this->opaded_key.ptr[i] = buffer[i] ^ 0x5C;
- }
-
- /* begin hashing of inner pad */
- this->h->reset(this->h);
- this->h->get_hash(this->h, this->ipaded_key, NULL);
-}
-
-/**
- * Implementation of hmac_t.destroy.
- */
-static void destroy(private_hmac_t *this)
-{
- this->h->destroy(this->h);
- free(this->opaded_key.ptr);
- free(this->ipaded_key.ptr);
- free(this);
-}
-
-/*
- * Described in header
- */
-hmac_t *hmac_create(hash_algorithm_t hash_algorithm)
-{
- private_hmac_t *this;
-
- this = malloc_thing(private_hmac_t);
-
- /* set hmac_t methods */
- this->hmac.get_mac = (void (*)(hmac_t *,chunk_t,u_int8_t*))get_mac;
- this->hmac.allocate_mac = (void (*)(hmac_t *,chunk_t,chunk_t*))allocate_mac;
- this->hmac.get_block_size = (size_t (*)(hmac_t *))get_block_size;
- this->hmac.set_key = (void (*)(hmac_t *,chunk_t))set_key;
- this->hmac.destroy = (void (*)(hmac_t *))destroy;
-
- /* set b, according to hasher */
- switch (hash_algorithm)
- {
- case HASH_SHA1:
- case HASH_MD5:
- case HASH_SHA256:
- this->b = 64;
- break;
- case HASH_SHA384:
- case HASH_SHA512:
- this->b = 128;
- break;
- default:
- free(this);
- return NULL;
- }
-
- /* build the hasher */
- this->h = hasher_create(hash_algorithm);
-
- /* build ipad and opad */
- this->opaded_key.ptr = malloc(this->b);
- this->opaded_key.len = this->b;
-
- this->ipaded_key.ptr = malloc(this->b);
- this->ipaded_key.len = this->b;
-
- return &(this->hmac);
-}
diff --git a/src/libstrongswan/crypto/hmac.h b/src/libstrongswan/crypto/hmac.h
deleted file mode 100644
index 06b75aaf9..000000000
--- a/src/libstrongswan/crypto/hmac.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * @file hmac.h
- *
- * @brief Interface of hmac_t.
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef HMAC_H_
-#define HMAC_H_
-
-typedef struct hmac_t hmac_t;
-
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief Message authentication using hash functions.
- *
- * This class implements the message authenticaion algorithm
- * described in RFC2104. It uses a hash function, wich must
- * be implemented as a hasher_t class.
- *
- * See http://www.faqs.org/rfcs/rfc2104.html for RFC.
- * @see
- * - hasher_t
- * - prf_hmac_t
- *
- * @b Constructors:
- * - hmac_create()
- *
- * @ingroup crypto
- */
-struct hmac_t {
- /**
- * @brief Generate message authentication code.
- *
- * If buffer is NULL, no result is given back. A next call will
- * append the data to already supplied data. If buffer is not NULL,
- * the mac of all apended data is calculated, returned and the
- * state of the hmac_t is reseted.
- *
- * @param this calling object
- * @param data chunk of data to authenticate
- * @param[out] buffer pointer where the generated bytes will be written
- */
- void (*get_mac) (hmac_t *this, chunk_t data, u_int8_t *buffer);
-
- /**
- * @brief Generates message authentication code and
- * allocate space for them.
- *
- * If chunk is NULL, no result is given back. A next call will
- * append the data to already supplied. If chunk is not NULL,
- * the mac of all apended data is calculated, returned and the
- * state of the hmac_t reset;
- *
- * @param this calling object
- * @param data chunk of data to authenticate
- * @param[out] chunk chunk which will hold generated bytes
- */
- void (*allocate_mac) (hmac_t *this, chunk_t data, chunk_t *chunk);
-
- /**
- * @brief Get the block size of this hmac_t object.
- *
- * @param this calling object
- * @return block size in bytes
- */
- size_t (*get_block_size) (hmac_t *this);
-
- /**
- * @brief Set the key for this hmac_t object.
- *
- * Any key length is accepted.
- *
- * @param this calling object
- * @param key key to set
- */
- void (*set_key) (hmac_t *this, chunk_t key);
-
- /**
- * @brief Destroys a hmac_t object.
- *
- * @param this calling object
- */
- void (*destroy) (hmac_t *this);
-};
-
-/**
- * @brief Creates a new hmac_t object.
- *
- * Creates a hasher_t object internally.
- *
- * @param hash_algorithm hash algorithm to use
- * @return
- * - hmac_t object
- * - NULL if hash algorithm is not supported
- *
- * @ingroup transforms
- */
-hmac_t *hmac_create(hash_algorithm_t hash_algorithm);
-
-#endif /*HMAC_H_*/
diff --git a/src/libstrongswan/crypto/ietf_attr_list.c b/src/libstrongswan/crypto/ietf_attr_list.c
deleted file mode 100644
index 1ecadf679..000000000
--- a/src/libstrongswan/crypto/ietf_attr_list.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/**
- * @file ietf_attr.c
- *
- * @brief Implementation of ietfAttr_t.
- *
- */
-
-/*
- * Copyright (C) 2007 Andreas Steffen, Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include <debug.h>
-#include <asn1/asn1.h>
-#include <utils/lexparser.h>
-
-#include "ietf_attr_list.h"
-
-/**
- * Private definition of ietfAttribute kinds
- */
-typedef enum {
- IETF_ATTRIBUTE_OCTETS = 0,
- IETF_ATTRIBUTE_OID = 1,
- IETF_ATTRIBUTE_STRING = 2
-} ietfAttribute_t;
-
-typedef struct ietfAttr_t ietfAttr_t;
-
-/**
- * Private definition of an ietfAttribute
- */
-struct ietfAttr_t {
- /**
- * IETF attribute kind
- */
- ietfAttribute_t kind;
-
- /**
- * IETF attribute valuse
- */
- chunk_t value;
-
- /**
- * Compares two ietfAttributes
- *
- * return -1 if this is earlier in the alphabet than other
- * return 0 if this equals other
- * return +1 if this is later in the alphabet than other
- *
- * @param this calling object
- * @param other other object
- */
- int (*compare) (const ietfAttr_t *this ,const ietfAttr_t *other);
-
- /**
- * Destroys the ietfAttr_t object.
- *
- * @param this ietfAttr_t to destroy
- */
- void (*destroy) (ietfAttr_t *this);
-};
-
-/**
- * Implements ietfAttr_t.compare.
- */
-static int ietfAttr_compare(const ietfAttr_t *this ,const ietfAttr_t *other)
-{
- int cmp_len, len, cmp_value;
-
- /* OID attributes are appended after STRING and OCTETS attributes */
- if (this->kind != IETF_ATTRIBUTE_OID && other->kind == IETF_ATTRIBUTE_OID)
- {
- return -1;
- }
- if (this->kind == IETF_ATTRIBUTE_OID && other->kind != IETF_ATTRIBUTE_OID)
- {
- return 1;
- }
-
- cmp_len = this->value.len - other->value.len;
- len = (cmp_len < 0)? this->value.len : other->value.len;
- cmp_value = memcmp(this->value.ptr, other->value.ptr, len);
-
- return (cmp_value == 0)? cmp_len : cmp_value;
-}
-
-/**
- * Implements ietfAttr_t.destroy.
- */
-static void ietfAttr_destroy(ietfAttr_t *this)
-{
- free(this->value.ptr);
- free(this);
-}
-
-/**
- * Creates an ietfAttr_t object.
- */
-static ietfAttr_t *ietfAttr_create(ietfAttribute_t kind, chunk_t value)
-{
- ietfAttr_t *this = malloc_thing(ietfAttr_t);
-
- /* initialize */
- this->kind = kind;
- this->value = chunk_clone(value);
-
- /* function */
- this->compare = ietfAttr_compare;
- this->destroy = ietfAttr_destroy;
-
- return this;
-}
-
-/**
- * Adds an ietfAttr_t object to a sorted linked list
- */
-static void ietfAttr_add(linked_list_t *list, ietfAttr_t *attr)
-{
- iterator_t *iterator = list->create_iterator(list, TRUE);
- ietfAttr_t *current_attr;
- bool found = FALSE;
-
- while (iterator->iterate(iterator, (void **)&current_attr))
- {
- int cmp = attr->compare(attr, current_attr);
-
- if (cmp > 0)
- {
- continue;
- }
- if (cmp == 0)
- {
- attr->destroy(attr);
- }
- else
- {
- iterator->insert_before(iterator, attr);
- }
- found = TRUE;
- break;
- }
- iterator->destroy(iterator);
- if (!found)
- {
- list->insert_last(list, attr);
- }
-}
-
-/*
- * Described in header.
- */
-bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b)
-{
- bool result = TRUE;
-
- /* lists must have the same number of attributes */
- if (list_a->get_count(list_a) != list_b->get_count(list_b))
- {
- return FALSE;
- }
- /* empty lists - no attributes */
- if (list_a->get_count(list_a) == 0)
- {
- return TRUE;
- }
-
- /* compare two alphabetically-sorted lists */
- {
- iterator_t *iterator_a = list_a->create_iterator(list_a, TRUE);
- iterator_t *iterator_b = list_b->create_iterator(list_b, TRUE);
- ietfAttr_t *attr_a, *attr_b;
-
- while (iterator_a->iterate(iterator_a, (void **)&attr_a) &&
- iterator_b->iterate(iterator_b, (void **)&attr_b))
- {
- if (attr_a->compare(attr_a, attr_b) != 0)
- {
- /* we have a mismatch */
- result = FALSE;
- break;
- }
- }
- iterator_a->destroy(iterator_a);
- iterator_b->destroy(iterator_b);
- }
- return result;
-}
-
-/*
- * Described in header.
- */
-void ietfAttr_list_list(linked_list_t *list, FILE *out)
-{
- iterator_t *iterator = list->create_iterator(list, TRUE);
- ietfAttr_t *attr;
- bool first = TRUE;
-
- while (iterator->iterate(iterator, (void **)&attr))
- {
- if (first)
- {
- first = FALSE;
- }
- else
- {
- fprintf(out, ", ");
- }
-
- switch (attr->kind)
- {
- case IETF_ATTRIBUTE_OCTETS:
- case IETF_ATTRIBUTE_STRING:
- fprintf(out, "%.*s", (int)attr->value.len, attr->value.ptr);
- break;
- case IETF_ATTRIBUTE_OID:
- {
- int oid = known_oid(attr->value);
-
- if (oid == OID_UNKNOWN)
- {
- fprintf(out, "0x#B", &attr->value);
- }
- else
- {
- fprintf(out, "%s", oid_names[oid]);
- }
- }
- break;
- default:
- break;
- }
- }
- iterator->destroy(iterator);
-}
-
-/*
- * Described in header.
- */
-void ietfAttr_list_create_from_string(char *msg, linked_list_t *list)
-{
- chunk_t line = { msg, strlen(msg) };
-
- while (eat_whitespace(&line))
- {
- chunk_t group;
-
- /* extract the next comma-separated group attribute */
- if (!extract_token(&group, ',', &line))
- {
- group = line;
- line.len = 0;
- }
-
- /* remove any trailing spaces */
- while (group.len > 0 && *(group.ptr + group.len - 1) == ' ')
- {
- group.len--;
- }
-
- /* add the group attribute to the list */
- if (group.len > 0)
- {
- ietfAttr_t *attr = ietfAttr_create(IETF_ATTRIBUTE_STRING, group);
-
- ietfAttr_add(list, attr);
- }
- }
-}
-
-/**
- * ASN.1 definition of ietfAttrSyntax
- */
-static const asn1Object_t ietfAttrSyntaxObjects[] =
-{
- { 0, "ietfAttrSyntax", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "policyAuthority", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_BODY }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
- { 1, "values", ASN1_SEQUENCE, ASN1_LOOP }, /* 3 */
- { 2, "octets", ASN1_OCTET_STRING, ASN1_OPT |
- ASN1_BODY }, /* 4 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
- { 2, "oid", ASN1_OID, ASN1_OPT |
- ASN1_BODY }, /* 6 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
- { 2, "string", ASN1_UTF8STRING, ASN1_OPT |
- ASN1_BODY }, /* 8 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 1, "end loop", ASN1_EOC, ASN1_END } /* 10 */
-};
-
-#define IETF_ATTR_OCTETS 4
-#define IETF_ATTR_OID 6
-#define IETF_ATTR_STRING 8
-#define IETF_ATTR_ROOF 11
-
-/*
- * Described in header.
- */
-void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, chunk, level0, FALSE, FALSE);
-
- while (objectID < IETF_ATTR_ROOF)
- {
- if (!extract_object(ietfAttrSyntaxObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
-
- switch (objectID)
- {
- case IETF_ATTR_OCTETS:
- case IETF_ATTR_OID:
- case IETF_ATTR_STRING:
- {
- ietfAttribute_t kind = (objectID - IETF_ATTR_OCTETS) / 2;
- ietfAttr_t *attr = ietfAttr_create(kind, object);
- ietfAttr_add(list, attr);
- }
- break;
- default:
- break;
- }
- objectID++;
- }
-}
-
-/*
- * Described in header.
- */
-chunk_t ietfAttr_list_encode(linked_list_t *list)
-{
- chunk_t ietfAttributes;
- size_t size = 0;
- u_char *pos;
- iterator_t *iterator = list->create_iterator(list, TRUE);
- ietfAttr_t *attr;
-
- /* precalculate the total size of all values */
- while (iterator->iterate(iterator, (void **)&attr))
- {
- size_t len = attr->value.len;
-
- size += 1 + (len > 0) + (len >= 128) + (len >= 256) + (len >= 65536) + len;
- }
- iterator->destroy(iterator);
-
- pos = build_asn1_object(&ietfAttributes, ASN1_SEQUENCE, size);
-
- iterator = list->create_iterator(list, TRUE);
- while (iterator->iterate(iterator, (void **)&attr))
- {
- chunk_t ietfAttribute;
- asn1_t type = ASN1_NULL;
-
- switch (attr->kind)
- {
- case IETF_ATTRIBUTE_OCTETS:
- type = ASN1_OCTET_STRING;
- break;
- case IETF_ATTRIBUTE_STRING:
- type = ASN1_UTF8STRING;
- break;
- case IETF_ATTRIBUTE_OID:
- type = ASN1_OID;
- break;
- }
- ietfAttribute = asn1_simple_object(type, attr->value);
-
- /* copy ietfAttribute into ietfAttributes chunk */
- memcpy(pos, ietfAttribute.ptr, ietfAttribute.len);
- pos += ietfAttribute.len;
- free(ietfAttribute.ptr);
- }
- iterator->destroy(iterator);
-
- return asn1_wrap(ASN1_SEQUENCE, "m", ietfAttributes);
-}
-
-/*
- * Described in header.
- */
-void ietfAttr_list_destroy(linked_list_t *list)
-{
- list->destroy_offset(list, offsetof(ietfAttr_t, destroy));
-}
diff --git a/src/libstrongswan/crypto/ietf_attr_list.h b/src/libstrongswan/crypto/ietf_attr_list.h
deleted file mode 100644
index 75407bbf6..000000000
--- a/src/libstrongswan/crypto/ietf_attr_list.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * @file ietf_attr_list.h
- *
- * @brief Handling of ietfAttr_t linked lists
- *
- */
-
-/*
- * Copyright (C) 2007 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef IETF_ATTR_LIST_H_
-#define IETF_ATTR_LIST_H_
-
-#include <library.h>
-#include <utils/linked_list.h>
-
-
-/**
- * @brief Compare two linked lists of ietfAttr_t objects for equality
- *
- * @param list_a first alphabetically-sorted list
- * @param list_b second alphabetically-sorted list
- * @return TRUE if equal
- *
- * @ingroup crypto
- */
-bool ietfAttr_list_equals(linked_list_t *list_a, linked_list_t *list_b);
-
-/**
- * @brief Lists a linked list of ietfAttr_t objects
- *
- * @param list alphabetically-sorted linked list of attributes
- @param out output file
- *
- * @ingroup crypto
- */
-void ietfAttr_list_list(linked_list_t *list, FILE *out);
-
-/**
- * @brief Create a linked list of ietfAttr_t objects from a string
- *
- * @param msg string with comma-separated group names
- * @param list alphabetically-sorted linked list of attributes
- *
- * @ingroup crypto
- */
-void ietfAttr_list_create_from_string(char *msg, linked_list_t *list);
-
-/**
- * @brief Create a linked list of ietfAttr_t objects from an ASN.1-coded chunk
- *
- * @param chunk chunk containing ASN.1-coded attributes
- * @param list alphabetically-sorted linked list of attributes
- * @param level0 parsing level
- */
-void ietfAttr_list_create_from_chunk(chunk_t chunk, linked_list_t *list, int level0);
-
-/**
- * @brief Encode a linked list of ietfAttr_t objects into an ASN.1-coded chunk
- *
- * @param list alphabetically-sorted linked list of attributes
- * @return chunk containing ASN.1-coded attributes
- */
-chunk_t ietfAttr_list_encode(linked_list_t *list);
-
-/**
- * @brief Destroys a linked list of ietfAttr_t objects
- *
- * @param list list to be destroyed
- *
- * @ingroup crypto
- */
-void ietfAttr_list_destroy(linked_list_t *list);
-
-#endif /* IETF_ATTR_LIST_H_ */
-
diff --git a/src/libstrongswan/crypto/ocsp.c b/src/libstrongswan/crypto/ocsp.c
deleted file mode 100644
index 4bbec31de..000000000
--- a/src/libstrongswan/crypto/ocsp.c
+++ /dev/null
@@ -1,934 +0,0 @@
-/**
- * @file ocsp.c
- *
- * @brief Implementation of ocsp_t.
- *
- */
-
-/* Support of the Online Certificate Status Protocol (OCSP)
- *
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Copyright (C) 2007 Andreas Steffen
- *
- * Hochschule für Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id$
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-
-#include <asn1/oid.h>
-#include <asn1/asn1.h>
-#include <utils/identification.h>
-#include <utils/randomizer.h>
-#include <utils/fetcher.h>
-#include <debug.h>
-
-#include "hashers/hasher.h"
-#include "rsa/rsa_public_key.h"
-#include "certinfo.h"
-#include "x509.h"
-#include "ocsp.h"
-
-#define NONCE_LENGTH 16
-
-typedef struct private_ocsp_t private_ocsp_t;
-
-/**
- * Private data of a ocsp_t object.
- */
-struct private_ocsp_t {
- /**
- * Public interface for this ocsp object.
- */
- ocsp_t public;
-
- /**
- * CA certificate.
- */
- x509_t *cacert;
-
- /**
- * Requestor certificate
- */
- x509_t *requestor_cert;
-
- /**
- * Linked list of ocsp uris
- */
- linked_list_t *uris;
-
- /**
- * Linked list of certinfos to be requested
- */
- linked_list_t *certinfos;
-
- /**
- * Nonce required for ocsp request and response
- */
- chunk_t nonce;
-
- /**
- * SHA-1 hash over issuer distinguished name
- */
- chunk_t authNameID;
-
- /**
- * SHA-1 hash over issuer public key
- */
- chunk_t authKeyID;
-};
-
-ENUM(response_status_names, STATUS_SUCCESSFUL, STATUS_UNAUTHORIZED,
- "successful",
- "malformed request",
- "internal error",
- "try later",
- "signature required",
- "unauthorized"
-);
-
-/* response container */
-typedef struct response_t response_t;
-
-struct response_t {
- chunk_t chunk;
- chunk_t tbs;
- identification_t *responder_id_name;
- chunk_t responder_id_key;
- time_t produced_at;
- chunk_t responses;
- chunk_t nonce;
- int algorithm;
- chunk_t signature;
- x509_t *responder_cert;
-
- /**
- * @brief Destroys the response_t object
- *
- * @param this response_t to destroy
- */
- void (*destroy) (response_t *this);
-};
-
-/**
- * Implements response_t.destroy.
- */
-static void response_destroy(response_t *this)
-{
- DESTROY_IF(this->responder_id_name);
- DESTROY_IF(this->responder_cert);
- free(this->chunk.ptr);
- free(this);
-}
-
-/**
- * Creates a response_t object
- */
-static response_t* response_create_from_chunk(chunk_t chunk)
-{
- response_t *this = malloc_thing(response_t);
-
- this->chunk = chunk;
- this->tbs = chunk_empty;
- this->responder_id_name = NULL;
- this->responder_id_key = chunk_empty;
- this->produced_at = UNDEFINED_TIME;
- this->responses = chunk_empty;
- this->nonce = chunk_empty;
- this->algorithm = OID_UNKNOWN;
- this->signature = chunk_empty;
- this->responder_cert = NULL;
-
- this->destroy = (void (*) (response_t*))response_destroy;
-
- return this;
-}
-
-/* some OCSP specific prefabricated ASN.1 constants */
-
-static u_char ASN1_nonce_oid_str[] = {
- 0x06, 0x09,
- 0x2B, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02
-};
-
-static u_char ASN1_response_oid_str[] = {
- 0x06, 0x09,
- 0x2B, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04
-};
-
-static u_char ASN1_response_content_str[] = {
- 0x04, 0x0D,
- 0x30, 0x0B,
- 0x06, 0x09,
- 0x2B, 0x06,
- 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01
-};
-
-static const chunk_t ASN1_nonce_oid = chunk_from_buf(ASN1_nonce_oid_str);
-static const chunk_t ASN1_response_oid = chunk_from_buf(ASN1_response_oid_str);
-static const chunk_t ASN1_response_content = chunk_from_buf(ASN1_response_content_str);
-
-/* asn.1 definitions for parsing */
-
-static const asn1Object_t ocspResponseObjects[] = {
- { 0, "OCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "responseStatus", ASN1_ENUMERATED, ASN1_BODY }, /* 1 */
- { 1, "responseBytesContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 2 */
- { 2, "responseBytes", ASN1_SEQUENCE, ASN1_NONE }, /* 3 */
- { 3, "responseType", ASN1_OID, ASN1_BODY }, /* 4 */
- { 3, "response", ASN1_OCTET_STRING, ASN1_BODY }, /* 5 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
-};
-
-#define OCSP_RESPONSE_STATUS 1
-#define OCSP_RESPONSE_TYPE 4
-#define OCSP_RESPONSE 5
-#define OCSP_RESPONSE_ROOF 7
-
-static const asn1Object_t basicResponseObjects[] = {
- { 0, "BasicOCSPResponse", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "tbsResponseData", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "versionContext", ASN1_CONTEXT_C_0, ASN1_NONE |
- ASN1_DEF }, /* 2 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 2, "responderIdContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 4 */
- { 3, "responderIdByName", ASN1_SEQUENCE, ASN1_OBJ }, /* 5 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
- { 2, "responderIdContext", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 7 */
- { 3, "responderIdByKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 8 */
- { 2, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 2, "producedAt", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 10 */
- { 2, "responses", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
- { 2, "responseExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 12 */
- { 3, "responseExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 13 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 14 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 15 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_BODY |
- ASN1_DEF }, /* 16 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 17 */
- { 4, "end loop", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 20 */
- { 1, "signature", ASN1_BIT_STRING, ASN1_BODY }, /* 21 */
- { 1, "certsContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 22 */
- { 2, "certs", ASN1_SEQUENCE, ASN1_LOOP }, /* 23 */
- { 3, "certificate", ASN1_SEQUENCE, ASN1_RAW }, /* 24 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 26 */
-};
-
-#define BASIC_RESPONSE_TBS_DATA 1
-#define BASIC_RESPONSE_VERSION 3
-#define BASIC_RESPONSE_ID_BY_NAME 5
-#define BASIC_RESPONSE_ID_BY_KEY 8
-#define BASIC_RESPONSE_PRODUCED_AT 10
-#define BASIC_RESPONSE_RESPONSES 11
-#define BASIC_RESPONSE_EXT_ID 15
-#define BASIC_RESPONSE_CRITICAL 16
-#define BASIC_RESPONSE_EXT_VALUE 17
-#define BASIC_RESPONSE_ALGORITHM 20
-#define BASIC_RESPONSE_SIGNATURE 21
-#define BASIC_RESPONSE_CERTIFICATE 24
-#define BASIC_RESPONSE_ROOF 27
-
-static const asn1Object_t responsesObjects[] = {
- { 0, "responses", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "singleResponse", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
-};
-
-#define RESPONSES_SINGLE_RESPONSE 1
-#define RESPONSES_ROOF 3
-
-static const asn1Object_t singleResponseObjects[] = {
- { 0, "singleResponse", ASN1_SEQUENCE, ASN1_BODY }, /* 0 */
- { 1, "certID", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 2 */
- { 2, "issuerNameHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 3 */
- { 2, "issuerKeyHash", ASN1_OCTET_STRING, ASN1_BODY }, /* 4 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 5 */
- { 1, "certStatusGood", ASN1_CONTEXT_S_0, ASN1_OPT }, /* 6 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
- { 1, "certStatusRevoked", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 8 */
- { 2, "revocationTime", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 9 */
- { 2, "revocationReason", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 10 */
- { 3, "crlReason", ASN1_ENUMERATED, ASN1_BODY }, /* 11 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 12 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 13 */
- { 1, "certStatusUnknown", ASN1_CONTEXT_S_2, ASN1_OPT }, /* 14 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 15 */
- { 1, "thisUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 16 */
- { 1, "nextUpdateContext", ASN1_CONTEXT_C_0, ASN1_OPT }, /* 17 */
- { 2, "nextUpdate", ASN1_GENERALIZEDTIME, ASN1_BODY }, /* 18 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 19 */
- { 1, "singleExtensionsContext", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 20 */
- { 2, "singleExtensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 21 */
- { 3, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 22 */
- { 4, "extnID", ASN1_OID, ASN1_BODY }, /* 23 */
- { 4, "critical", ASN1_BOOLEAN, ASN1_BODY |
- ASN1_DEF }, /* 24 */
- { 4, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 25 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 27 */
-};
-
-#define SINGLE_RESPONSE_ALGORITHM 2
-#define SINGLE_RESPONSE_ISSUER_NAME_HASH 3
-#define SINGLE_RESPONSE_ISSUER_KEY_HASH 4
-#define SINGLE_RESPONSE_SERIAL_NUMBER 5
-#define SINGLE_RESPONSE_CERT_STATUS_GOOD 6
-#define SINGLE_RESPONSE_CERT_STATUS_REVOKED 8
-#define SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME 9
-#define SINGLE_RESPONSE_CERT_STATUS_CRL_REASON 11
-#define SINGLE_RESPONSE_CERT_STATUS_UNKNOWN 14
-#define SINGLE_RESPONSE_THIS_UPDATE 16
-#define SINGLE_RESPONSE_NEXT_UPDATE 18
-#define SINGLE_RESPONSE_EXT_ID 23
-#define SINGLE_RESPONSE_CRITICAL 24
-#define SINGLE_RESPONSE_EXT_VALUE 25
-#define SINGLE_RESPONSE_ROOF 28
-
-/**
- * build requestorName (into TBSRequest)
- */
-static chunk_t build_requestor_name(private_ocsp_t *this)
-{
- identification_t *requestor_name = this->requestor_cert->get_subject(this->requestor_cert);
-
- return asn1_wrap(ASN1_CONTEXT_C_1, "m",
- asn1_simple_object(ASN1_CONTEXT_C_4,
- requestor_name->get_encoding(requestor_name)));
-}
-
-/**
- * build request (into requestList)
- * no singleRequestExtensions used
- */
-static chunk_t build_request(private_ocsp_t *this, certinfo_t *certinfo)
-{
- chunk_t serialNumber = certinfo->get_serialNumber(certinfo);
-
- chunk_t reqCert = asn1_wrap(ASN1_SEQUENCE, "cmmm",
- asn1_algorithmIdentifier(OID_SHA1),
- asn1_simple_object(ASN1_OCTET_STRING, this->authNameID),
- asn1_simple_object(ASN1_OCTET_STRING, this->authKeyID),
- asn1_simple_object(ASN1_INTEGER, serialNumber));
-
- return asn1_wrap(ASN1_SEQUENCE, "m", reqCert);
-}
-
-/**
- * build requestList (into TBSRequest)
- */
-static chunk_t build_request_list(private_ocsp_t *this)
-{
- chunk_t requestList;
- size_t datalen = 0;
- linked_list_t *request_list = linked_list_create();
-
- {
- iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
- certinfo_t *certinfo;
-
- while (iterator->iterate(iterator, (void**)&certinfo))
- {
- chunk_t *request = malloc_thing(chunk_t);
-
- *request = build_request(this, certinfo);
- request_list->insert_last(request_list, (void*)request);
- datalen += request->len;
- }
- iterator->destroy(iterator);
- }
- {
- iterator_t *iterator = request_list->create_iterator(request_list, TRUE);
- chunk_t *request;
-
- u_char *pos = build_asn1_object(&requestList, ASN1_SEQUENCE, datalen);
-
- while (iterator->iterate(iterator, (void**)&request))
- {
- memcpy(pos, request->ptr, request->len);
- pos += request->len;
- free(request->ptr);
- free(request);
- }
- iterator->destroy(iterator);
- request_list->destroy(request_list);
- }
- return requestList;
-}
-
-/**
- * build nonce extension (into requestExtensions)
- */
-static chunk_t build_nonce_extension(private_ocsp_t *this)
-{
- randomizer_t *randomizer = randomizer_create();
-
- /* generate a random nonce */
- randomizer->allocate_pseudo_random_bytes(randomizer, NONCE_LENGTH, &this->nonce);
- randomizer->destroy(randomizer);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm",
- ASN1_nonce_oid,
- asn1_simple_object(ASN1_OCTET_STRING, this->nonce));
-}
-
-/**
- * build requestExtensions (into TBSRequest)
- */
-static chunk_t build_request_ext(private_ocsp_t *this)
-{
- return asn1_wrap(ASN1_CONTEXT_C_2, "m",
- asn1_wrap(ASN1_SEQUENCE, "mm",
- build_nonce_extension(this),
- asn1_wrap(ASN1_SEQUENCE, "cc",
- ASN1_response_oid,
- ASN1_response_content
- )
- )
- );
-}
-
-/**
- * build TBSRequest (into OCSPRequest)
- */
-static chunk_t build_tbs_request(private_ocsp_t *this, bool has_requestor_cert)
-{
- /* version is skipped since the default is ok */
- return asn1_wrap(ASN1_SEQUENCE, "mmm",
- (has_requestor_cert)? build_requestor_name(this): chunk_empty,
- build_request_list(this),
- build_request_ext(this));
-}
-
-/**
- * build signature into ocsp request
- * gets built only if a request cert with a corresponding private key is found
- */
-static chunk_t build_signature(private_ocsp_t *this, chunk_t tbsRequest)
-{
- /* TODO */
- return chunk_empty;
-}
-
-/**
- * assembles an ocsp request and sets the nonce field in private_ocsp_t to the sent nonce
- */
-static chunk_t ocsp_build_request(private_ocsp_t *this)
-{
- bool has_requestor_cert;
- chunk_t keyid = this->cacert->get_keyid(this->cacert);
- chunk_t tbsRequest, signature;
-
- DBG2("assembling ocsp request");
- DBG2("issuer: '%D'", this->cacert->get_subject(this->cacert));
- DBG2("keyid: %#B", &keyid);
-
- /* looks for requestor cert and matching private key */
- has_requestor_cert = FALSE;
-
- /* TODO has_requestor_cert = get_ocsp_requestor_cert(location); */
-
- /* build content */
- tbsRequest = build_tbs_request(this, has_requestor_cert);
-
- /* sign tbsReuqest */
- signature = (has_requestor_cert)? build_signature(this, tbsRequest): chunk_empty;
-
- return asn1_wrap(ASN1_SEQUENCE, "mm",
- tbsRequest,
- signature);
-
- return signature;
-}
-
-/**
- * parse a basic OCSP response
- */
-static bool ocsp_parse_basic_response(chunk_t blob, int level0, response_t *res)
-{
- u_int level, version;
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- int objectID = 0;
- int extn_oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < BASIC_RESPONSE_ROOF)
- {
- if (!extract_object(basicResponseObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- switch (objectID)
- {
- case BASIC_RESPONSE_TBS_DATA:
- res->tbs = object;
- break;
- case BASIC_RESPONSE_VERSION:
- version = (object.len)? (1 + (u_int)*object.ptr) : 1;
- if (version != OCSP_BASIC_RESPONSE_VERSION)
- {
- DBG1("wrong ocsp basic response version (version= %i)", version);
- return FALSE;
- }
- break;
- case BASIC_RESPONSE_ID_BY_NAME:
- res->responder_id_name = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", res->responder_id_name);
- break;
- case BASIC_RESPONSE_ID_BY_KEY:
- res->responder_id_key = object;
- break;
- case BASIC_RESPONSE_PRODUCED_AT:
- res->produced_at = asn1totime(&object, ASN1_GENERALIZEDTIME);
- break;
- case BASIC_RESPONSE_RESPONSES:
- res->responses = object;
- break;
- case BASIC_RESPONSE_EXT_ID:
- extn_oid = known_oid(object);
- break;
- case BASIC_RESPONSE_CRITICAL:
- critical = object.len && *object.ptr;
- DBG2(" %s", critical? "TRUE" : "FALSE");
- break;
- case BASIC_RESPONSE_EXT_VALUE:
- if (extn_oid == OID_NONCE)
- res->nonce = object;
- break;
- case BASIC_RESPONSE_ALGORITHM:
- res->algorithm = parse_algorithmIdentifier(object, level+1, NULL);
- break;
- case BASIC_RESPONSE_SIGNATURE:
- res->signature = object;
- break;
- case BASIC_RESPONSE_CERTIFICATE:
- {
- chunk_t blob = chunk_clone(object);
-
- res->responder_cert = x509_create_from_chunk(blob, level+1);
- }
- break;
- }
- objectID++;
- }
- return TRUE;
-}
-
-/**
- * parse an ocsp response and return the result as a response_t struct
- */
-static response_status ocsp_parse_response(response_t *res)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int ocspResponseType = OID_UNKNOWN;
- response_status rStatus = STATUS_INTERNALERROR;
-
- asn1_init(&ctx, res->chunk, 0, FALSE, FALSE);
-
- while (objectID < OCSP_RESPONSE_ROOF)
- {
- if (!extract_object(ocspResponseObjects, &objectID, &object, &level, &ctx))
- {
- return STATUS_INTERNALERROR;
- }
-
- switch (objectID)
- {
- case OCSP_RESPONSE_STATUS:
- rStatus = (response_status) *object.ptr;
- DBG2(" '%N'", response_status_names, rStatus);
-
- switch (rStatus)
- {
- case STATUS_SUCCESSFUL:
- break;
- case STATUS_MALFORMEDREQUEST:
- case STATUS_INTERNALERROR:
- case STATUS_TRYLATER:
- case STATUS_SIGREQUIRED:
- case STATUS_UNAUTHORIZED:
- DBG1("unsuccessful ocsp response: server said '%N'",
- response_status_names, rStatus);
- return rStatus;
- default:
- return STATUS_INTERNALERROR;
- }
- break;
- case OCSP_RESPONSE_TYPE:
- ocspResponseType = known_oid(object);
- break;
- case OCSP_RESPONSE:
- {
- switch (ocspResponseType)
- {
- case OID_BASIC:
- if (!ocsp_parse_basic_response(object, level+1, res))
- {
- return STATUS_INTERNALERROR;
- }
- break;
- default:
- DBG1("ocsp response is not of type BASIC");
- DBG1("ocsp response OID: %#B", &object);
- return STATUS_INTERNALERROR;
- }
- }
- break;
- }
- objectID++;
- }
- return rStatus;
-}
-
-/**
- * Check if the OCSP response has a valid signature
- */
-static bool ocsp_valid_response(response_t *res, x509_t *ocsp_cert)
-{
- rsa_public_key_t *public_key;
- time_t until = UNDEFINED_TIME;
- err_t ugh;
- hash_algorithm_t algorithm = hasher_algorithm_from_oid(res->algorithm);
-
- if (algorithm == HASH_UNKNOWN)
- {
- DBG1("unknown signature algorithm");
- return FALSE;
- }
-
- DBG2("verifying ocsp response signature:");
- DBG2("signer: '%D'", ocsp_cert->get_subject(ocsp_cert));
- DBG2("issuer: '%D'", ocsp_cert->get_issuer(ocsp_cert));
-
- ugh = ocsp_cert->is_valid(ocsp_cert, &until);
- if (ugh != NULL)
- {
- DBG1("ocsp signer certificate %s", ugh);
- return FALSE;
- }
- public_key = ocsp_cert->get_public_key(ocsp_cert);
-
- return public_key->verify_emsa_pkcs1_signature(public_key, algorithm, res->tbs, res->signature) == SUCCESS;
-}
-
-/**
- * parse a single OCSP response
- */
-static bool ocsp_parse_single_response(private_ocsp_t *this, chunk_t blob, int level0)
-{
- u_int level, extn_oid;
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- int objectID = 0;
-
- certinfo_t *certinfo = NULL;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < SINGLE_RESPONSE_ROOF)
- {
- if (!extract_object(singleResponseObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- switch (objectID)
- {
- case SINGLE_RESPONSE_ALGORITHM:
- if (parse_algorithmIdentifier(object, level+1, NULL) != OID_SHA1)
- {
- DBG1("only sha-1 hash supported in ocsp single response");
- return FALSE;
- }
- break;
- case SINGLE_RESPONSE_ISSUER_NAME_HASH:
- if (!chunk_equals(object, this->authNameID))
- {
- DBG1("ocsp single response has wrong issuer name hash");
- return FALSE;
- }
- break;
- case SINGLE_RESPONSE_ISSUER_KEY_HASH:
- if (!chunk_equals(object, this->authKeyID))
- {
- DBG1("ocsp single response has wrong issuer key hash");
- return FALSE;
- }
- break;
- case SINGLE_RESPONSE_SERIAL_NUMBER:
- {
- iterator_t *iterator = this->certinfos->create_iterator(this->certinfos, TRUE);
- certinfo_t *current_certinfo;
-
- while (iterator->iterate(iterator, (void**)&current_certinfo))
- {
- if (chunk_equals(object, current_certinfo->get_serialNumber(current_certinfo)))
- {
- certinfo = current_certinfo;
- }
- }
- iterator->destroy(iterator);
- if (certinfo == NULL)
- {
- DBG1("unrequested serial number in ocsp single response");
- return FALSE;
- }
- }
- break;
- case SINGLE_RESPONSE_CERT_STATUS_GOOD:
- certinfo->set_status(certinfo, CERT_GOOD);
- break;
- case SINGLE_RESPONSE_CERT_STATUS_REVOKED:
- certinfo->set_status(certinfo, CERT_REVOKED);
- break;
- case SINGLE_RESPONSE_CERT_STATUS_REVOCATION_TIME:
- certinfo->set_revocationTime(certinfo,
- asn1totime(&object, ASN1_GENERALIZEDTIME));
- break;
- case SINGLE_RESPONSE_CERT_STATUS_CRL_REASON:
- certinfo->set_revocationReason(certinfo,
- (object.len == 1) ? *object.ptr : REASON_UNSPECIFIED);
- break;
- case SINGLE_RESPONSE_CERT_STATUS_UNKNOWN:
- certinfo->set_status(certinfo, CERT_UNKNOWN);
- break;
- case SINGLE_RESPONSE_THIS_UPDATE:
- certinfo->set_thisUpdate(certinfo,
- asn1totime(&object, ASN1_GENERALIZEDTIME));
- break;
- case SINGLE_RESPONSE_NEXT_UPDATE:
- certinfo->set_nextUpdate(certinfo,
- asn1totime(&object, ASN1_GENERALIZEDTIME));
- break;
- case SINGLE_RESPONSE_EXT_ID:
- extn_oid = known_oid(object);
- break;
- case SINGLE_RESPONSE_CRITICAL:
- critical = object.len && *object.ptr;
- DBG2(" %s", critical ? "TRUE" : "FALSE");
- case SINGLE_RESPONSE_EXT_VALUE:
- break;
- }
- objectID++;
- }
- return TRUE;
-}
-
-/**
- * verify and process ocsp response and update the ocsp cache
- */
-static void ocsp_process_response(private_ocsp_t *this, response_t *res, credential_store_t *credentials)
-{
- x509_t *ocsp_cert = NULL;
-
- /* parse the ocsp response without looking at the single responses yet */
- response_status status = ocsp_parse_response(res);
-
- if (status != STATUS_SUCCESSFUL)
- {
- DBG1("error in ocsp response");
- return;
- }
-
- /* check if there was a nonce in the request */
- if (this->nonce.ptr != NULL && res->nonce.ptr == NULL)
- {
- DBG1("ocsp response contains no nonce, replay attack possible");
- }
-
- /* check if the nonces are identical */
- if (res->nonce.ptr != NULL && !chunk_equals(res->nonce, this->nonce))
- {
- DBG1("invalid nonce in ocsp response");
- return;
- }
-
- /* check if we received a trusted responder certificate */
- if (res->responder_cert)
- {
- if (res->responder_cert->is_ocsp_signer(res->responder_cert))
- {
- DBG2("received certificate is ocsp signer");
- if (credentials->is_trusted(credentials, "OCSP signing", res->responder_cert))
- {
- DBG1("received ocsp signer certificate is trusted");
- ocsp_cert = credentials->add_auth_certificate(credentials,
- res->responder_cert, AUTH_OCSP);
- res->responder_cert = NULL;
- }
- else
- {
- DBG1("received ocsp signer certificate is not trusted - rejected");
- }
- }
- else
- {
- DBG1("received certificate is no ocsp signer - rejected");
- }
- }
-
- /* if we didn't receive a trusted responder cert, search the credential store */
- if (ocsp_cert == NULL)
- {
- ocsp_cert = credentials->get_auth_certificate(credentials,
- AUTH_OCSP|AUTH_CA, res->responder_id_name);
- if (ocsp_cert == NULL)
- {
- DBG1("no ocsp signer certificate found");
- return;
- }
- }
-
- /* check the response signature */
- if (!ocsp_valid_response(res, ocsp_cert))
- {
- DBG1("ocsp response signature is invalid");
- return;
- }
- DBG2("ocsp response signature is valid");
-
- /* now parse the single responses one at a time */
- {
- u_int level;
- asn1_ctx_t ctx;
- chunk_t object;
- int objectID = 0;
-
- asn1_init(&ctx, res->responses, 0, FALSE, FALSE);
-
- while (objectID < RESPONSES_ROOF)
- {
- if (!extract_object(responsesObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
- if (objectID == RESPONSES_SINGLE_RESPONSE)
- {
- ocsp_parse_single_response(this, object, level+1);
- }
- objectID++;
- }
- }
-}
-
-/**
- * Implements ocsp_t.fetch.
- */
-static void fetch(private_ocsp_t *this, certinfo_t *certinfo, credential_store_t *credentials)
-{
- chunk_t request;
- response_t *response = NULL;
-
- if (this->uris->get_count(this->uris) == 0)
- {
- return;
- }
- this->certinfos->insert_last(this->certinfos, (void*)certinfo);
-
- request = ocsp_build_request(this);
- DBG3("ocsp request: %B", &request);
- {
- iterator_t *iterator = this->uris->create_iterator(this->uris, TRUE);
- identification_t *uri;
-
- while (iterator->iterate(iterator, (void**)&uri))
- {
- fetcher_t *fetcher;
- char uri_string[BUF_LEN];
- chunk_t uri_chunk = uri->get_encoding(uri);
- chunk_t response_chunk;
-
- snprintf(uri_string, BUF_LEN, "%.*s", uri_chunk.len, uri_chunk.ptr);
- fetcher = fetcher_create(uri_string);
-
- response_chunk = fetcher->post(fetcher, "application/ocsp-request", request);
- fetcher->destroy(fetcher);
- if (response_chunk.ptr != NULL)
- {
- response = response_create_from_chunk(response_chunk);
- break;
- }
- }
- iterator->destroy(iterator);
- }
- free(request.ptr);
-
- if (response == NULL)
- {
- return;
- }
- DBG3("ocsp response: %B", &response->chunk);
- ocsp_process_response(this, response, credentials);
- response->destroy(response);
-}
-
-/**
- * Implements ocsp_t.destroy.
- */
-static void destroy(private_ocsp_t *this)
-{
- this->certinfos->destroy(this->certinfos);
- free(this->authNameID.ptr);
- free(this->nonce.ptr);
- free(this);
-}
-
-/*
- * Described in header.
- */
-ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris)
-{
- private_ocsp_t *this = malloc_thing(private_ocsp_t);
-
- /* initialize */
- this->cacert = cacert;
- this->uris = uris;
- this->certinfos = linked_list_create();
- this->nonce = chunk_empty;
- this->authKeyID = cacert->get_subjectKeyID(cacert);
- {
- hasher_t *hasher = hasher_create(HASH_SHA1);
- identification_t *issuer = cacert->get_subject(cacert);
-
- hasher->allocate_hash(hasher, issuer->get_encoding(issuer),
- &this->authNameID);
- hasher->destroy(hasher);
- }
-
- /* public functions */
- this->public.fetch = (void (*) (ocsp_t*,certinfo_t*,credential_store_t*))fetch;
- this->public.destroy = (void (*) (ocsp_t*))destroy;
-
- return &this->public;
-}
diff --git a/src/libstrongswan/crypto/ocsp.h b/src/libstrongswan/crypto/ocsp.h
deleted file mode 100644
index e468bb8be..000000000
--- a/src/libstrongswan/crypto/ocsp.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * @file ocsp.h
- *
- * @brief Interface of ocsp_t
- *
- */
-
-/* Support of the Online Certificate Status Protocol (OCSP) Support
- *
- * Copyright (C) 2003 Christoph Gysin, Simon Zwahlen
- * Copyright (C) 2007 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id$
- */
-
-#ifndef OCSP_H_
-#define OCSP_H_
-
-typedef struct ocsp_t ocsp_t;
-
-#include <credential_store.h>
-#include <utils/linked_list.h>
-
-#include "certinfo.h"
-
-/* constants */
-#define OCSP_BASIC_RESPONSE_VERSION 1
-#define OCSP_DEFAULT_VALID_TIME 120 /* validity of one-time response in seconds */
-#define OCSP_WARNING_INTERVAL 2 /* days */
-
-/* OCSP response status */
-typedef enum {
- STATUS_SUCCESSFUL = 0,
- STATUS_MALFORMEDREQUEST = 1,
- STATUS_INTERNALERROR = 2,
- STATUS_TRYLATER = 3,
- STATUS_SIGREQUIRED = 5,
- STATUS_UNAUTHORIZED= 6
-} response_status;
-
-/**
- * @brief Online Certficate Status Protocol (OCSP)
- *
- * @ingroup transforms
- */
-struct ocsp_t {
-
- /**
- * @brief Fetches the actual certificate status via OCSP
- *
- * @param uris linked list of ocsp uris
- * @param certinfo certificate status info to be updated
- * @param credentials credential store needed for trust path verification
- */
- void (*fetch) (ocsp_t *this, certinfo_t *certinfo, credential_store_t *credentials);
-
- /**
- * @brief Destroys the ocsp_t object.
- *
- * @param this ocsp object to destroy
- */
- void (*destroy) (ocsp_t *this);
-
-};
-
-/**
- * @brief Create an ocsp_t object.
- *
- * @param cacert ca certificate
- * @param uris linked list of ocsp uris
- * @return created ocsp_t object
- *
- * @ingroup transforms
- */
-ocsp_t *ocsp_create(x509_t *cacert, linked_list_t *uris);
-
-#endif /* OCSP_H_ */
diff --git a/src/libstrongswan/crypto/pkcs7.c b/src/libstrongswan/crypto/pkcs7.c
deleted file mode 100644
index 48d3e2d78..000000000
--- a/src/libstrongswan/crypto/pkcs7.c
+++ /dev/null
@@ -1,1077 +0,0 @@
-/**
- * @file pkcs7.c
- *
- * @brief Implementation of pkcs7_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: pkcs7.c 3438 2008-02-02 00:29:03Z andreas $
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <library.h>
-#include "debug.h"
-
-#include <asn1/asn1.h>
-#include <asn1/oid.h>
-#include <crypto/x509.h>
-#include <crypto/pkcs9.h>
-#include <crypto/hashers/hasher.h>
-#include <crypto/crypters/crypter.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <utils/randomizer.h>
-#include <utils/linked_list.h>
-
-#include "pkcs7.h"
-
-typedef struct private_pkcs7_t private_pkcs7_t;
-
-/**
- * Private data of a pkcs7_t object.
- */
-struct private_pkcs7_t {
- /**
- * Public interface for this certificate.
- */
- pkcs7_t public;
-
- /**
- * contentInfo type
- */
- int type;
-
- /**
- * ASN.1 encoded content
- */
- chunk_t content;
-
- /**
- * Has the content already been parsed?
- */
- bool parsed;
-
- /**
- * ASN.1 parsing start level
- */
- u_int level;
-
- /**
- * retrieved data
- */
- chunk_t data;
-
- /**
- * ASN.1 encoded attributes
- */
- pkcs9_t *attributes;
-
- /**
- * Linked list of X.509 certificates
- */
- linked_list_t *certs;
-};
-
-/**
- * ASN.1 definition of the PKCS#7 ContentInfo type
- */
-static const asn1Object_t contentInfoObjects[] = {
- { 0, "contentInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "contentType", ASN1_OID, ASN1_BODY }, /* 1 */
- { 1, "content", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_BODY }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
-};
-
-#define PKCS7_INFO_TYPE 1
-#define PKCS7_INFO_CONTENT 2
-#define PKCS7_INFO_ROOF 4
-
-/**
- * ASN.1 definition of the PKCS#7 signedData type
- */
-static const asn1Object_t signedDataObjects[] = {
- { 0, "signedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "digestAlgorithms", ASN1_SET, ASN1_LOOP }, /* 2 */
- { 2, "algorithm", ASN1_EOC, ASN1_RAW }, /* 3 */
- { 1, "end loop", ASN1_EOC, ASN1_END }, /* 4 */
- { 1, "contentInfo", ASN1_EOC, ASN1_RAW }, /* 5 */
- { 1, "certificates", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_LOOP }, /* 6 */
- { 2, "certificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 7 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 8 */
- { 1, "crls", ASN1_CONTEXT_C_1, ASN1_OPT |
- ASN1_LOOP }, /* 9 */
- { 2, "crl", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END }, /* 11 */
- { 1, "signerInfos", ASN1_SET, ASN1_LOOP }, /* 12 */
- { 2, "signerInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 13 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 14 */
- { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 15 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 16 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 17 */
- { 3, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 18 */
- { 3, "authenticatedAttributes", ASN1_CONTEXT_C_0, ASN1_OPT |
- ASN1_OBJ }, /* 19 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 20 */
- { 3, "digestEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 21 */
- { 3, "encryptedDigest", ASN1_OCTET_STRING, ASN1_BODY }, /* 22 */
- { 3, "unauthenticatedAttributes", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 23 */
- { 3, "end opt", ASN1_EOC, ASN1_END }, /* 24 */
- { 1, "end loop", ASN1_EOC, ASN1_END } /* 25 */
-};
-
-#define PKCS7_DIGEST_ALG 3
-#define PKCS7_SIGNED_CONTENT_INFO 5
-#define PKCS7_SIGNED_CERT 7
-#define PKCS7_SIGNER_INFO 13
-#define PKCS7_SIGNED_ISSUER 16
-#define PKCS7_SIGNED_SERIAL_NUMBER 17
-#define PKCS7_DIGEST_ALGORITHM 18
-#define PKCS7_AUTH_ATTRIBUTES 19
-#define PKCS7_DIGEST_ENC_ALGORITHM 21
-#define PKCS7_ENCRYPTED_DIGEST 22
-#define PKCS7_SIGNED_ROOF 26
-
-/**
- * ASN.1 definition of the PKCS#7 envelopedData type
- */
-static const asn1Object_t envelopedDataObjects[] = {
- { 0, "envelopedData", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "recipientInfos", ASN1_SET, ASN1_LOOP }, /* 2 */
- { 2, "recipientInfo", ASN1_SEQUENCE, ASN1_BODY }, /* 3 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 3, "issuerAndSerialNumber", ASN1_SEQUENCE, ASN1_BODY }, /* 5 */
- { 4, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
- { 4, "serial", ASN1_INTEGER, ASN1_BODY }, /* 7 */
- { 3, "encryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 8 */
- { 3, "encryptedKey", ASN1_OCTET_STRING, ASN1_BODY }, /* 9 */
- { 1, "end loop", ASN1_EOC, ASN1_END }, /* 10 */
- { 1, "encryptedContentInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 11 */
- { 2, "contentType", ASN1_OID, ASN1_BODY }, /* 12 */
- { 2, "contentEncryptionAlgorithm", ASN1_EOC, ASN1_RAW }, /* 13 */
- { 2, "encryptedContent", ASN1_CONTEXT_S_0, ASN1_BODY } /* 14 */
-};
-
-#define PKCS7_ENVELOPED_VERSION 1
-#define PKCS7_RECIPIENT_INFO_VERSION 4
-#define PKCS7_ISSUER 6
-#define PKCS7_SERIAL_NUMBER 7
-#define PKCS7_ENCRYPTION_ALG 8
-#define PKCS7_ENCRYPTED_KEY 9
-#define PKCS7_CONTENT_TYPE 12
-#define PKCS7_CONTENT_ENC_ALGORITHM 13
-#define PKCS7_ENCRYPTED_CONTENT 14
-#define PKCS7_ENVELOPED_ROOF 15
-
-/**
- * PKCS7 contentInfo OIDs
- */
-static u_char ASN1_pkcs7_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x01
-};
-
-static u_char ASN1_pkcs7_signed_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x02
-};
-
-static u_char ASN1_pkcs7_enveloped_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x03
-};
-
-static u_char ASN1_pkcs7_signed_enveloped_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x04
-};
-
-static u_char ASN1_pkcs7_digested_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x05
-};
-
-static char ASN1_pkcs7_encrypted_data_oid_str[] = {
- 0x06, 0x09,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x07, 0x06
-};
-
-static const chunk_t ASN1_pkcs7_data_oid =
- chunk_from_buf(ASN1_pkcs7_data_oid_str);
-static const chunk_t ASN1_pkcs7_signed_data_oid =
- chunk_from_buf(ASN1_pkcs7_signed_data_oid_str);
-static const chunk_t ASN1_pkcs7_enveloped_data_oid =
- chunk_from_buf(ASN1_pkcs7_enveloped_data_oid_str);
-static const chunk_t ASN1_pkcs7_signed_enveloped_data_oid =
- chunk_from_buf(ASN1_pkcs7_signed_enveloped_data_oid_str);
-static const chunk_t ASN1_pkcs7_digested_data_oid =
- chunk_from_buf(ASN1_pkcs7_digested_data_oid_str);
-static const chunk_t ASN1_pkcs7_encrypted_data_oid =
- chunk_from_buf(ASN1_pkcs7_encrypted_data_oid_str);
-
-/**
- * 3DES and DES encryption OIDs
- */
-static u_char ASN1_3des_ede_cbc_oid_str[] = {
- 0x06, 0x08,
- 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x03, 0x07
-};
-
-static u_char ASN1_des_cbc_oid_str[] = {
- 0x06, 0x05,
- 0x2B, 0x0E, 0x03, 0x02, 0x07
-};
-
-static const chunk_t ASN1_3des_ede_cbc_oid =
- chunk_from_buf(ASN1_3des_ede_cbc_oid_str);
-static const chunk_t ASN1_des_cbc_oid =
- chunk_from_buf(ASN1_des_cbc_oid_str);
-
-/**
- * Implements pkcs7_t.is_data.
- */
-static bool is_data(private_pkcs7_t *this)
-{
- return this->type == OID_PKCS7_DATA;
-}
-
-/**
- * Implements pkcs7_t.is_signedData.
- */
-static bool is_signedData(private_pkcs7_t *this)
-{
- return this->type == OID_PKCS7_SIGNED_DATA;
-}
-
-/**
- * Implements pkcs7_t.is_envelopedData.
- */
-static bool is_envelopedData(private_pkcs7_t *this)
-{
- return this->type == OID_PKCS7_ENVELOPED_DATA;
-}
-
-/**
- * Check whether to abort the requested parsing
- */
-static bool abort_parsing(private_pkcs7_t *this, int type)
-{
- if (this->type != type)
- {
- DBG1("pkcs7 content to be parsed is not of type '%s'",
- oid_names[type]);
- return TRUE;
- }
- if (this->parsed)
- {
- DBG1("pkcs7 content has already been parsed");
- return TRUE;
- }
- this->parsed = TRUE;
- return FALSE;
-}
-
-/**
- * Implements pkcs7_t.parse_data.
- */
-static bool parse_data(private_pkcs7_t *this)
-{
- chunk_t data = this->content;
-
- if (abort_parsing(this, OID_PKCS7_DATA))
- {
- return FALSE;
- }
- if (data.len == 0)
- {
- this->data = chunk_empty;
- return TRUE;
- }
- if (parse_asn1_simple_object(&data, ASN1_OCTET_STRING, this->level, "data"))
- {
- this->data = chunk_clone(data);
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-/**
- * Implements pkcs7_t.parse_signedData.
- */
-static bool parse_signedData(private_pkcs7_t *this, x509_t *cacert)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- int digest_alg = OID_UNKNOWN;
- int enc_alg = OID_UNKNOWN;
- int signerInfos = 0;
-
- chunk_t encrypted_digest = chunk_empty;
-
- if (abort_parsing(this, OID_PKCS7_SIGNED_DATA))
- {
- return FALSE;
- }
-
- asn1_init(&ctx, this->content, this->level, FALSE, FALSE);
-
- while (objectID < PKCS7_SIGNED_ROOF)
- {
- if (!extract_object(signedDataObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- switch (objectID)
- {
- case PKCS7_DIGEST_ALG:
- digest_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_SIGNED_CONTENT_INFO:
- {
- chunk_t pureData;
- pkcs7_t *data = pkcs7_create_from_chunk(object, level+1);
-
- if (data == NULL)
- {
- return FALSE;
- }
- if (!data->parse_data(data))
- {
- data->destroy(data);
- return FALSE;
- }
- pureData = data->get_data(data);
- this->data = (pureData.len)? chunk_clone(pureData) : chunk_empty;
- data->destroy(data);
- }
- break;
- case PKCS7_SIGNED_CERT:
- {
- x509_t *cert = x509_create_from_chunk(chunk_clone(object), level+1);
-
- if (cert)
- {
- this->certs->insert_last(this->certs, (void*)cert);
- }
- }
- break;
- case PKCS7_SIGNER_INFO:
- signerInfos++;
- DBG2(" signer #%d", signerInfos);
- break;
- case PKCS7_SIGNED_ISSUER:
- {
- identification_t *issuer;
-
- issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", issuer);
- issuer->destroy(issuer);
- }
- break;
- case PKCS7_AUTH_ATTRIBUTES:
- *object.ptr = ASN1_SET;
- this->attributes = pkcs9_create_from_chunk(object, level+1);
- *object.ptr = ASN1_CONTEXT_C_0;
- break;
- case PKCS7_DIGEST_ALGORITHM:
- digest_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_DIGEST_ENC_ALGORITHM:
- enc_alg = parse_algorithmIdentifier(object, level, NULL);
- break;
- case PKCS7_ENCRYPTED_DIGEST:
- encrypted_digest = object;
- }
- objectID++;
- }
-
- /* check the signature only if a cacert is available */
- if (cacert != NULL)
- {
- hash_algorithm_t algorithm = hasher_algorithm_from_oid(digest_alg);
- rsa_public_key_t *signer = cacert->get_public_key(cacert);
-
- if (signerInfos == 0)
- {
- DBG1("no signerInfo object found");
- return FALSE;
- }
- else if (signerInfos > 1)
- {
- DBG1("more than one signerInfo object found");
- return FALSE;
- }
- if (this->attributes == NULL)
- {
- DBG1("no authenticatedAttributes object found");
- return FALSE;
- }
- if (enc_alg != OID_RSA_ENCRYPTION)
- {
- DBG1("only RSA digest encryption supported");
- return FALSE;
- }
- if (signer->verify_emsa_pkcs1_signature(signer, algorithm,
- this->attributes->get_encoding(this->attributes), encrypted_digest) != SUCCESS)
- {
- DBG1("invalid digest signature");
- return FALSE;
- }
- else
- {
- DBG2("digest signature is valid");
- }
- if (this->data.ptr != NULL)
- {
- chunk_t messageDigest = this->attributes->get_messageDigest(this->attributes);
-
- if (messageDigest.ptr == NULL)
- {
- DBG1("messageDigest attribute not found");
- return FALSE;
- }
- else
- {
- hasher_t *hasher = hasher_create(algorithm);
- chunk_t hash;
- bool valid;
-
- hasher->allocate_hash(hasher, this->data, &hash);
- hasher->destroy(hasher);
- DBG3("hash: %B", &hash);
-
- valid = chunk_equals(messageDigest, hash);
- free(messageDigest.ptr);
- free(hash.ptr);
- if (valid)
- {
- DBG2("messageDigest is valid");
- }
- else
- {
- DBG1("invalid messageDigest");
- return FALSE;
- }
- }
- }
- }
- return TRUE;
-}
-
-/**
- * Parse PKCS#7 envelopedData content
- */
-static bool parse_envelopedData(private_pkcs7_t *this, chunk_t serialNumber,
- rsa_private_key_t *key)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- chunk_t iv = chunk_empty;
- chunk_t symmetric_key = chunk_empty;
- chunk_t encrypted_content = chunk_empty;
-
- crypter_t *crypter = NULL;
-
- if (abort_parsing(this, OID_PKCS7_ENVELOPED_DATA))
- {
- return FALSE;
- }
-
- asn1_init(&ctx, this->content, this->level, FALSE, FALSE);
-
- while (objectID < PKCS7_ENVELOPED_ROOF)
- {
- if (!extract_object(envelopedDataObjects, &objectID, &object, &level, &ctx))
- {
- goto failed;
- }
-
- switch (objectID)
- {
- case PKCS7_ENVELOPED_VERSION:
- if (*object.ptr != 0)
- {
- DBG1("envelopedData version is not 0");
- goto failed;
- }
- break;
- case PKCS7_RECIPIENT_INFO_VERSION:
- if (*object.ptr != 0)
- {
- DBG1("recipient info version is not 0");
- goto failed;
- }
- break;
- case PKCS7_ISSUER:
- {
- identification_t *issuer;
-
- issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", issuer);
- issuer->destroy(issuer);
- }
- break;
- case PKCS7_SERIAL_NUMBER:
- if (!chunk_equals(serialNumber, object))
- {
- DBG1("serial numbers do not match");
- goto failed;
- }
- break;
- case PKCS7_ENCRYPTION_ALG:
- {
- int alg = parse_algorithmIdentifier(object, level, NULL);
-
- if (alg != OID_RSA_ENCRYPTION)
- {
- DBG1("only rsa encryption supported");
- goto failed;
- }
- }
- break;
- case PKCS7_ENCRYPTED_KEY:
- if (key->pkcs1_decrypt(key, object, &symmetric_key) != SUCCESS)
- {
- DBG1("symmetric key could not be decrypted with rsa");
- goto failed;
- }
- DBG4("symmetric key : %B", &symmetric_key);
- break;
- case PKCS7_CONTENT_TYPE:
- if (known_oid(object) != OID_PKCS7_DATA)
- {
- DBG1("encrypted content not of type pkcs7 data");
- goto failed;
- }
- break;
- case PKCS7_CONTENT_ENC_ALGORITHM:
- {
- int alg = parse_algorithmIdentifier(object, level, &iv);
-
- switch (alg)
- {
- case OID_DES_CBC:
- crypter = crypter_create(ENCR_DES, 0);
- break;
- case OID_3DES_EDE_CBC:
- crypter = crypter_create(ENCR_3DES, 0);
- break;
- default:
- DBG1("Only DES and 3DES supported for symmetric encryption");
- goto failed;
- }
- if (symmetric_key.len != crypter->get_key_size(crypter))
- {
- DBG1("symmetric key has wrong length");
- goto failed;
- }
- if (!parse_asn1_simple_object(&iv, ASN1_OCTET_STRING, level+1, "IV"))
- {
- DBG1("IV could not be parsed");
- goto failed;
- }
- if (iv.len != crypter->get_block_size(crypter))
- {
- DBG1("IV has wrong length");
- goto failed;
- }
- }
- break;
- case PKCS7_ENCRYPTED_CONTENT:
- encrypted_content = object;
- break;
- }
- objectID++;
- }
-
- /* decrypt the content */
- crypter->set_key(crypter, symmetric_key);
- crypter->decrypt(crypter, encrypted_content, iv, &this->data);
- DBG3("decrypted content with padding: %B", &this->data);
-
- /* remove the padding */
- {
- u_char *pos = this->data.ptr + this->data.len - 1;
- u_char pattern = *pos;
- size_t padding = pattern;
-
- if (padding > this->data.len)
- {
- DBG1("padding greater than data length");
- goto failed;
- }
- this->data.len -= padding;
-
- while (padding-- > 0)
- {
- if (*pos-- != pattern)
- {
- DBG1("wrong padding pattern");
- goto failed;
- }
- }
- }
- crypter->destroy(crypter);
- free(symmetric_key.ptr);
- return TRUE;
-
-failed:
- DESTROY_IF(crypter);
- free(symmetric_key.ptr);
- chunk_free(&this->data);
- return FALSE;
-}
-
-/**
- * Implements pkcs7_t.get_data.
- */
-static chunk_t get_data(private_pkcs7_t *this)
-{
- return this->data;
-}
-
-/**
- * Implements pkcs7_t.get_contentInfo.
- */
-static chunk_t get_contentInfo(private_pkcs7_t *this)
-{
- chunk_t content_type;
-
- /* select DER-encoded OID for pkcs7_contentInfo type */
- switch(this->type)
- {
- case OID_PKCS7_DATA:
- content_type = ASN1_pkcs7_data_oid;
- break;
- case OID_PKCS7_SIGNED_DATA:
- content_type = ASN1_pkcs7_signed_data_oid;
- break;
- case OID_PKCS7_ENVELOPED_DATA:
- content_type = ASN1_pkcs7_enveloped_data_oid;
- break;
- case OID_PKCS7_SIGNED_ENVELOPED_DATA:
- content_type = ASN1_pkcs7_signed_enveloped_data_oid;
- break;
- case OID_PKCS7_DIGESTED_DATA:
- content_type = ASN1_pkcs7_digested_data_oid;
- break;
- case OID_PKCS7_ENCRYPTED_DATA:
- content_type = ASN1_pkcs7_encrypted_data_oid;
- break;
- case OID_UNKNOWN:
- default:
- DBG1("invalid pkcs7 contentInfo type");
- return chunk_empty;
- }
-
- return (this->content.ptr == NULL)
- ? asn1_simple_object(ASN1_SEQUENCE, content_type)
- : asn1_wrap(ASN1_SEQUENCE, "cm",
- content_type,
- asn1_simple_object(ASN1_CONTEXT_C_0, this->content)
- );
-}
-
-/**
- * Implements pkcs7_t.create_certificate_iterator
- */
-static iterator_t *create_certificate_iterator(const private_pkcs7_t *this)
-{
- return this->certs->create_iterator(this->certs, TRUE);
-}
-
-/**
- * Implements pkcs7_t.set_certificate
- */
-static void set_certificate(private_pkcs7_t *this, x509_t *cert)
-{
- if (cert)
- {
- /* TODO the certificate is currently not cloned */
- this->certs->insert_last(this->certs, cert);
- }
-}
-
-/**
- * Implements pkcs7_t.set_attributes
- */
-static void set_attributes(private_pkcs7_t *this, pkcs9_t *attributes)
-{
- this->attributes = attributes;
-}
-
-/**
- * build a DER-encoded issuerAndSerialNumber object
- */
-chunk_t pkcs7_build_issuerAndSerialNumber(x509_t *cert)
-{
- identification_t *issuer = cert->get_issuer(cert);
-
- return asn1_wrap(ASN1_SEQUENCE, "cm",
- issuer->get_encoding(issuer),
- asn1_simple_object(ASN1_INTEGER, cert->get_serialNumber(cert)));
-}
-
-/**
- * Implements pkcs7_t.build_envelopedData.
- */
-bool build_envelopedData(private_pkcs7_t *this, x509_t *cert,
- encryption_algorithm_t alg)
-{
- chunk_t iv, symmetricKey, in, out, alg_oid;
- crypter_t *crypter;
-
- /* select OID of symmetric encryption algorithm */
- switch (alg)
- {
- case ENCR_DES:
- alg_oid = ASN1_des_cbc_oid;
- break;
- case ENCR_3DES:
- alg_oid = ASN1_3des_ede_cbc_oid;
- break;
- default:
- DBG1(" encryption algorithm %N not supported",
- encryption_algorithm_names, alg);
- return FALSE;
- }
-
- crypter = crypter_create(alg, 0);
- if (crypter == NULL)
- {
- DBG1(" could not create crypter for algorithm %N",
- encryption_algorithm_names, alg);
- return FALSE;
- }
-
- /* generate a true random symmetric encryption key
- * and a pseudo-random iv
- */
- {
- randomizer_t *randomizer = randomizer_create();
-
- randomizer->allocate_random_bytes(randomizer,
- crypter->get_key_size(crypter), &symmetricKey);
- DBG4(" symmetric encryption key: %B", &symmetricKey);
-
- randomizer->allocate_pseudo_random_bytes(randomizer,
- crypter->get_block_size(crypter), &iv);
- DBG4(" initialization vector: %B", &iv);
-
- randomizer->destroy(randomizer);
- }
-
- /* pad the data so that the total length becomes
- * a multiple of the block size
- */
- {
- size_t block_size = crypter->get_block_size(crypter);
- size_t padding = block_size - this->data.len % block_size;
-
- in.len = this->data.len + padding;
- in.ptr = malloc(in.len);
-
- DBG2(" padding %d bytes of data to multiple block size of %d bytes",
- (int)this->data.len, (int)in.len);
-
- /* copy data */
- memcpy(in.ptr, this->data.ptr, this->data.len);
- /* append padding */
- memset(in.ptr + this->data.len, padding, padding);
- }
- DBG3(" padded unencrypted data: %B", &in);
-
- /* symmetric encryption of data object */
- crypter->set_key(crypter, symmetricKey);
- crypter->encrypt(crypter, in, iv, &out);
- crypter->destroy(crypter);
- chunk_free_randomized(&in);
- DBG3(" encrypted data: %B", &out);
-
- /* build pkcs7 enveloped data object */
- {
- chunk_t contentEncryptionAlgorithm = asn1_wrap(ASN1_SEQUENCE, "cm",
- alg_oid,
- asn1_wrap(ASN1_OCTET_STRING, "m", iv));
-
- chunk_t encryptedContentInfo = asn1_wrap(ASN1_SEQUENCE, "cmm",
- ASN1_pkcs7_data_oid,
- contentEncryptionAlgorithm,
- asn1_wrap(ASN1_CONTEXT_S_0, "m", out));
-
- chunk_t wrappedKey, encryptedKey, recipientInfo;
-
- rsa_public_key_t *public_key = cert->get_public_key(cert);
-
- public_key->pkcs1_encrypt(public_key, symmetricKey, &wrappedKey);
- chunk_free_randomized(&symmetricKey);
-
- encryptedKey = asn1_wrap(ASN1_OCTET_STRING, "m", wrappedKey);
-
- recipientInfo = asn1_wrap(ASN1_SEQUENCE, "cmcm",
- ASN1_INTEGER_0,
- pkcs7_build_issuerAndSerialNumber(cert),
- asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
- encryptedKey);
-
- this->content = asn1_wrap(ASN1_SEQUENCE, "cmm",
- ASN1_INTEGER_0,
- asn1_wrap(ASN1_SET, "m", recipientInfo),
- encryptedContentInfo);
- this->type = OID_PKCS7_ENVELOPED_DATA;
- }
- return TRUE;
-}
-
-/**
- * Implements pkcs7_t.build_signedData.
- */
-bool build_signedData(private_pkcs7_t *this, rsa_private_key_t *private_key,
- hash_algorithm_t alg)
-{
- int signature_oid = hasher_signature_algorithm_to_oid(alg);
- chunk_t authenticatedAttributes = chunk_empty;
- chunk_t encryptedDigest = chunk_empty;
- chunk_t signerInfo;
- x509_t *cert;
-
- if (this->certs->get_first(this->certs, (void**)&cert) != SUCCESS)
- {
- DBG1(" no pkcs7 signer certificate found");
- return FALSE;
- }
-
- if (this->attributes != NULL)
- {
- if (this->data.ptr != NULL)
- {
- /* take the current time as signingTime */
- time_t now = time(NULL);
- chunk_t signingTime = timetoasn1(&now, ASN1_UTCTIME);
-
- chunk_t messageDigest, attributes;
- hasher_t *hasher = hasher_create(alg);
-
- hasher->allocate_hash(hasher, this->data, &messageDigest);
- hasher->destroy(hasher);
- this->attributes->set_attribute(this->attributes,
- OID_PKCS9_CONTENT_TYPE, ASN1_pkcs7_data_oid);
- this->attributes->set_messageDigest(this->attributes,
- messageDigest);
- this->attributes->set_attribute(this->attributes,
- OID_PKCS9_SIGNING_TIME, signingTime);
- attributes = this->attributes->get_encoding(this->attributes);
-
- free(messageDigest.ptr);
- free(signingTime.ptr);
-
- private_key->build_emsa_pkcs1_signature(private_key, alg,
- attributes, &encryptedDigest);
- authenticatedAttributes = chunk_clone(attributes);
- *authenticatedAttributes.ptr = ASN1_CONTEXT_C_0;
- }
- }
- else if (this->data.ptr != NULL)
- {
- private_key->build_emsa_pkcs1_signature(private_key, alg,
- this->data, &encryptedDigest);
- }
- if (encryptedDigest.ptr)
- {
- encryptedDigest = asn1_wrap(ASN1_OCTET_STRING, "m", encryptedDigest);
- }
-
- signerInfo = asn1_wrap(ASN1_SEQUENCE, "cmcmcm",
- ASN1_INTEGER_1,
- pkcs7_build_issuerAndSerialNumber(cert),
- asn1_algorithmIdentifier(signature_oid),
- authenticatedAttributes,
- asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
- encryptedDigest);
-
- if (this->data.ptr != NULL)
- {
- this->content = asn1_simple_object(ASN1_OCTET_STRING, this->data);
- chunk_free(&this->data);
- }
- this->type = OID_PKCS7_DATA;
- this->data = get_contentInfo(this);
- chunk_free(&this->content);
-
- this->type = OID_PKCS7_SIGNED_DATA;
-
- this->content = asn1_wrap(ASN1_SEQUENCE, "cmcmm",
- ASN1_INTEGER_1,
- asn1_simple_object(ASN1_SET, asn1_algorithmIdentifier(signature_oid)),
- this->data,
- asn1_simple_object(ASN1_CONTEXT_C_0, cert->get_certificate(cert)),
- asn1_wrap(ASN1_SET, "m", signerInfo));
-
- return TRUE;
-}
-
-/**
- * Implements pkcs7_t.destroy
- */
-static void destroy(private_pkcs7_t *this)
-{
- DESTROY_IF(this->attributes);
- this->certs->destroy_offset(this->certs, offsetof(x509_t, destroy));
- free(this->content.ptr);
- free(this->data.ptr);
- free(this);
-}
-
-/**
- * Parse PKCS#7 contentInfo object
- */
-static bool parse_contentInfo(chunk_t blob, u_int level0, private_pkcs7_t *cInfo)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < PKCS7_INFO_ROOF)
- {
- if (!extract_object(contentInfoObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- if (objectID == PKCS7_INFO_TYPE)
- {
- cInfo->type = known_oid(object);
- if (cInfo->type < OID_PKCS7_DATA
- || cInfo->type > OID_PKCS7_ENCRYPTED_DATA)
- {
- DBG1("unknown pkcs7 content type");
- return FALSE;
- }
- }
- else if (objectID == PKCS7_INFO_CONTENT && object.len > 0)
- {
- cInfo->content = chunk_clone(object);
- }
- objectID++;
- }
- return TRUE;
-}
-
-/**
- * Generic private constructor
- */
-static private_pkcs7_t *pkcs7_create_empty(void)
-{
- private_pkcs7_t *this = malloc_thing(private_pkcs7_t);
-
- /* initialize */
- this->type = OID_UNKNOWN;
- this->content = chunk_empty;
- this->parsed = FALSE;
- this->level = 0;
- this->data = chunk_empty;
- this->attributes = NULL;
- this->certs = linked_list_create();
-
- /*public functions */
- this->public.is_data = (bool (*) (pkcs7_t*))is_data;
- this->public.is_signedData = (bool (*) (pkcs7_t*))is_signedData;
- this->public.is_envelopedData = (bool (*) (pkcs7_t*))is_envelopedData;
- this->public.parse_data = (bool (*) (pkcs7_t*))parse_data;
- this->public.parse_signedData = (bool (*) (pkcs7_t*,x509_t*))parse_signedData;
- this->public.parse_envelopedData = (bool (*) (pkcs7_t*,chunk_t,rsa_private_key_t*))parse_envelopedData;
- this->public.get_data = (chunk_t (*) (pkcs7_t*))get_data;
- this->public.get_contentInfo = (chunk_t (*) (pkcs7_t*))get_contentInfo;
- this->public.create_certificate_iterator = (iterator_t* (*) (pkcs7_t*))create_certificate_iterator;
- this->public.set_certificate = (void (*) (pkcs7_t*,x509_t*))set_certificate;
- this->public.set_attributes = (void (*) (pkcs7_t*,pkcs9_t*))set_attributes;
- this->public.build_envelopedData = (bool (*) (pkcs7_t*,x509_t*,encryption_algorithm_t))build_envelopedData;
- this->public.build_signedData = (bool (*) (pkcs7_t*,rsa_private_key_t*,hash_algorithm_t))build_signedData;
- this->public.destroy = (void (*) (pkcs7_t*))destroy;
-
- return this;
-}
-
-/*
- * Described in header.
- */
-pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level)
-{
- private_pkcs7_t *this = pkcs7_create_empty();
-
- this->level = level + 2;
- if (!parse_contentInfo(chunk, level, this))
- {
- destroy(this);
- return NULL;
- }
- return &this->public;
-}
-
-/*
- * Described in header.
- */
-pkcs7_t *pkcs7_create_from_data(chunk_t data)
-{
- private_pkcs7_t *this = pkcs7_create_empty();
-
- this->data = chunk_clone(data);
- this->parsed = TRUE;
-
- return &this->public;
-}
-
-/*
- * Described in header.
- */
-pkcs7_t *pkcs7_create_from_file(const char *filename, const char *label)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
- char cert_label[BUF_LEN];
- pkcs7_t *pkcs7;
-
- snprintf(cert_label, BUF_LEN, "%s pkcs7", label);
-
- if (!pem_asn1_load_file(filename, NULL, cert_label, &chunk, &pgp))
- {
- return NULL;
- }
-
- pkcs7 = pkcs7_create_from_chunk(chunk, 0);
- free(chunk.ptr);
- return pkcs7;
-}
diff --git a/src/libstrongswan/crypto/pkcs7.h b/src/libstrongswan/crypto/pkcs7.h
deleted file mode 100644
index 74bd25361..000000000
--- a/src/libstrongswan/crypto/pkcs7.h
+++ /dev/null
@@ -1,209 +0,0 @@
-/**
- * @file pkcs7.h
- *
- * @brief Interface of pkcs7_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter, Martin Willi
- * Copyright (C) 2002-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil, Switzerland
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: pkcs7.h 3437 2008-02-01 22:26:01Z andreas $
- */
-
-#ifndef _PKCS7_H
-#define _PKCS7_H
-
-typedef struct pkcs7_t pkcs7_t;
-
-#include <library.h>
-#include <crypto/x509.h>
-#include <crypto/pkcs9.h>
-#include <crypto/rsa/rsa_private_key.h>
-#include <crypto/crypters/crypter.h>
-#include <utils/iterator.h>
-
-/**
- * @brief PKCS#7 contentInfo object.
- *
- * @b Constructors:
- * -pkcs7_create_from_chunk()
- * -pkcs7_create_from_data()
- *
- * @ingroup crypto
- */
-struct pkcs7_t {
- /**
- * @brief Check if the PKCS#7 contentType is data
- *
- * @param this calling object
- * @return TRUE if the contentType is data
- */
- bool (*is_data) (pkcs7_t *this);
-
- /**
- * @brief Check if the PKCS#7 contentType is signedData
- *
- * @param this calling object
- * @return TRUE if the contentType is signedData
- */
- bool (*is_signedData) (pkcs7_t *this);
-
- /**
- * @brief Check if the PKCS#7 contentType is envelopedData
- *
- * @param this calling object
- * @return TRUE if the contentType is envelopedData
- */
- bool (*is_envelopedData) (pkcs7_t *this);
-
- /**
- * @brief Parse a PKCS#7 data content.
- *
- * @param this calling object
- * @return TRUE if parsing was successful
- */
- bool (*parse_data) (pkcs7_t *this);
-
- /**
- * @brief Parse a PKCS#7 signedData content.
- *
- * @param this calling object
- * @param cacert cacert used to verify the signature
- * @return TRUE if parsing was successful
- */
- bool (*parse_signedData) (pkcs7_t *this, x509_t *cacert);
-
- /**
- * @brief Parse a PKCS#7 envelopedData content.
- *
- * @param this calling object
- * @param serialNumber serialNumber of the request
- * @param key RSA private key used to decrypt the symmetric key
- * @return TRUE if parsing was successful
- */
- bool (*parse_envelopedData) (pkcs7_t *this, chunk_t serialNumber, rsa_private_key_t *key);
-
- /**
- * @brief Returns the parsed data object
- *
- * @param this calling object
- * @return chunk containing the data object
- */
- chunk_t (*get_data) (pkcs7_t *this);
-
- /**
- * @brief Returns the a DER-encoded contentInfo object
- *
- * @param this calling object
- * @return chunk containing the contentInfo object
- */
- chunk_t (*get_contentInfo) (pkcs7_t *this);
-
- /**
- * @brief Create an iterator for the certificates.
- *
- * @param this calling object
- * @return iterator for the certificates
- */
- iterator_t *(*create_certificate_iterator) (pkcs7_t *this);
-
- /**
- * @brief Add a certificate.
- *
- * @param this calling object
- * @param cert certificate to be included
- */
- void (*set_certificate) (pkcs7_t *this, x509_t *cert);
-
- /**
- * @brief Add authenticated attributes.
- *
- * @param this calling object
- * @param attributes attributes to be included
- */
- void (*set_attributes) (pkcs7_t *this, pkcs9_t *attributes);
-
- /**
- * @brief Build a data object
- *
- * @param this PKCS#7 data to be built
- * @return TRUE if build was successful
- */
- bool (*build_data) (pkcs7_t *this);
-
- /**
- * @brief Build an envelopedData object
- *
- * @param this PKCS#7 data object to envelop
- * @param cert receivers's certificate
- * @param alg encryption algorithm
- * @return TRUE if build was successful
- */
- bool (*build_envelopedData) (pkcs7_t *this, x509_t *cert, encryption_algorithm_t alg);
-
- /**
- * @brief Build an signedData object
- *
- * @param this PKCS#7 data object to sign
- * @param key signer's RSA private key
- * @param alg digest algorithm used for signature
- * @return TRUE if build was successful
- */
- bool (*build_signedData) (pkcs7_t *this, rsa_private_key_t *key, hash_algorithm_t alg);
-
- /**
- * @brief Destroys the contentInfo object.
- *
- * @param this PKCS#7 contentInfo object to destroy
- */
- void (*destroy) (pkcs7_t *this);
-};
-
-/**
- * @brief Read a PKCS#7 contentInfo object from a DER encoded chunk.
- *
- * @param chunk chunk containing DER encoded data
- * @param level ASN.1 parsing start level
- * @return created pkcs7_contentInfo object, or NULL if invalid.
- *
- * @ingroup crypto
- */
-pkcs7_t *pkcs7_create_from_chunk(chunk_t chunk, u_int level);
-
-/**
- * @brief Create a PKCS#7 contentInfo object
- *
- * @param chunk chunk containing data
- * @return created pkcs7_contentInfo object.
- *
- * @ingroup crypto
- */
-pkcs7_t *pkcs7_create_from_data(chunk_t data);
-
-/**
- * @brief Read a X.509 certificate from a DER encoded file.
- *
- * @param filename file containing DER encoded data
- * @param label label describing kind of PKCS#7 file
- * @return created pkcs7_t object, or NULL if invalid.
- *
- * @ingroup crypto
- */
-pkcs7_t *pkcs7_create_from_file(const char *filename, const char *label);
-
-
-#endif /* _PKCS7_H */
diff --git a/src/libstrongswan/crypto/pkcs9.c b/src/libstrongswan/crypto/pkcs9.c
index 1003c9011..1c1b5a586 100644
--- a/src/libstrongswan/crypto/pkcs9.c
+++ b/src/libstrongswan/crypto/pkcs9.c
@@ -1,13 +1,5 @@
-/**
- * @file pkcs9.c
- *
- * @brief Implementation of pkcs9_t.
- *
- */
-
/*
* Copyright (C)2008 Andreas Steffen
- *
* Hochschule fuer Technik Rapperswil, Switzerland
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: pkcs7.c 3423 2008-01-22 10:32:37Z andreas $
+ * $Id: pkcs9.c 3891 2008-04-28 16:00:52Z andreas $
*/
#include <library.h>
@@ -28,6 +20,7 @@
#include <asn1/oid.h>
#include <asn1/asn1.h>
+#include <asn1/asn1_parser.h>
#include <utils/linked_list.h>
#include "pkcs9.h"
@@ -84,22 +77,6 @@ struct attribute_t {
};
-/* ASN.1 definition of the X.501 atttribute type */
-
-static const asn1Object_t attributesObjects[] = {
- { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */
- { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */
- { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */
- { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */
- { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
-};
-
-#define ATTRIBUTE_OBJ_TYPE 2
-#define ATTRIBUTE_OBJ_VALUE 4
-#define ATTRIBUTE_OBJ_ROOF 7
-
/**
* PKCS#9 attribute type OIDs
*/
@@ -267,7 +244,7 @@ static void build_encoding(private_pkcs9_t *this)
/* allocate memory for the attributes and build the encoding */
{
- u_char *pos = build_asn1_object(&this->encoding, ASN1_SET, attributes_len);
+ u_char *pos = asn1_build_object(&this->encoding, ASN1_SET, attributes_len);
iterator = this->attributes->create_iterator(this->attributes, TRUE);
@@ -335,7 +312,8 @@ static chunk_t get_messageDigest(private_pkcs9_t *this)
{
return chunk_empty;
}
- if (!parse_asn1_simple_object(&value, asn1_attributeType(oid), 0, oid_names[oid].name))
+ if (!asn1_parse_simple_object(&value, asn1_attributeType(oid), 0,
+ oid_names[oid].name))
{
return chunk_empty;
}
@@ -398,29 +376,41 @@ pkcs9_t *pkcs9_create(void)
}
/**
+ * ASN.1 definition of the X.501 atttribute type
+ */
+static const asn1Object_t attributesObjects[] = {
+ { 0, "attributes", ASN1_SET, ASN1_LOOP }, /* 0 */
+ { 1, "attribute", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
+ { 2, "type", ASN1_OID, ASN1_BODY }, /* 2 */
+ { 2, "values", ASN1_SET, ASN1_LOOP }, /* 3 */
+ { 3, "value", ASN1_EOC, ASN1_RAW }, /* 4 */
+ { 2, "end loop", ASN1_EOC, ASN1_END }, /* 5 */
+ { 0, "end loop", ASN1_EOC, ASN1_END }, /* 6 */
+ { 0, "exit", ASN1_EOC, ASN1_EXIT }
+};
+#define ATTRIBUTE_OBJ_TYPE 2
+#define ATTRIBUTE_OBJ_VALUE 4
+
+/**
* Parse a PKCS#9 attribute list
*/
static bool parse_attributes(chunk_t chunk, int level0, private_pkcs9_t* this)
{
- asn1_ctx_t ctx;
+ asn1_parser_t *parser;
chunk_t object;
- u_int level;
+ int objectID;
int oid = OID_UNKNOWN;
- int objectID = 0;
+ bool success = FALSE;
- asn1_init(&ctx, chunk, level0, FALSE, FALSE);
+ parser = asn1_parser_create(attributesObjects, chunk);
+ parser->set_top_level(parser, level0);
- while (objectID < ATTRIBUTE_OBJ_ROOF)
+ while (parser->iterate(parser, &objectID, &object))
{
- if (!extract_object(attributesObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
switch (objectID)
{
case ATTRIBUTE_OBJ_TYPE:
- oid = known_oid(object);
+ oid = asn1_known_oid(object);
break;
case ATTRIBUTE_OBJ_VALUE:
if (oid == OID_UNKNOWN)
@@ -431,7 +421,8 @@ static bool parse_attributes(chunk_t chunk, int level0, private_pkcs9_t* this)
{
attribute_t *attribute = attribute_create(oid, object);
- this->attributes->insert_last(this->attributes, (void*)attribute);
+ this->attributes->insert_last(this->attributes,
+ (void*)attribute);
}
/* parse known attributes */
{
@@ -439,16 +430,21 @@ static bool parse_attributes(chunk_t chunk, int level0, private_pkcs9_t* this)
if (type != ASN1_EOC)
{
- if (!parse_asn1_simple_object(&object, type, level+1, oid_names[oid].name))
+ if (!asn1_parse_simple_object(&object, type,
+ parser->get_level(parser)+1,
+ oid_names[oid].name))
{
- return FALSE;
+ goto end;
}
}
}
}
- objectID++;
}
- return TRUE;
+ success = parser->success(parser);
+
+end:
+ parser->destroy(parser);
+ return success;
}
diff --git a/src/libstrongswan/crypto/pkcs9.h b/src/libstrongswan/crypto/pkcs9.h
index 44915720c..89cdec83d 100644
--- a/src/libstrongswan/crypto/pkcs9.h
+++ b/src/libstrongswan/crypto/pkcs9.h
@@ -1,13 +1,5 @@
-/**
- * @file pkcs7.h
- *
- * @brief Interface of pkcs9_t.
- *
- */
-
/*
- * Copyright (C) 2008 Andreas Steffen
- *
+ * Copyright (C) 2008 Andreas Steffen
* Hochschule fuer Technik Rapperswil, Switzerland
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,102 +12,89 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * RCSID $Id: pkcs7.h 3423 2008-01-22 10:32:37Z andreas $
+ * $Id: pkcs9.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup pkcs9 pkcs9
+ * @{ @ingroup crypto
*/
-#ifndef _PKCS9_H
-#define _PKCS9_H
+#ifndef PKCS9_H_
+#define PKCS9_H_
typedef struct pkcs9_t pkcs9_t;
#include <library.h>
/**
- * @brief PKCS#9 .
- *
- * @b Constructors:
- * -pkcs9_create_from_chunk()
- * -pkcs9_create()
- *
- * @ingroup crypto
+ * PKCS#9 attributes.
*/
struct pkcs9_t {
+
/**
- * @brief generate ASN.1 encoding of attribute list
- *
- * @param this PKCS#9 attribute list to be encoded
+ * Generate ASN.1 encoding of attribute list
*/
void (*build_encoding) (pkcs9_t *this);
/**
- * @brief gets ASN.1 encoding of PKCS#9 attribute list
+ * Gets ASN.1 encoding of PKCS#9 attribute list
*
- * @param this calling object
* @return ASN.1 encoded PKCSI#9 list
*/
chunk_t (*get_encoding) (pkcs9_t *this);
/**
- * @brief gets a PKCS#9 attribute
+ * Gets a PKCS#9 attribute
*
- * @param this calling object
* @param oid OID of the attribute
* @return ASN.1 encoded value of the attribute
*/
chunk_t (*get_attribute) (pkcs9_t *this, int oid);
/**
- * @brief adds a PKCS#9 attribute
+ * Adds a PKCS#9 attribute
*
- * @param this calling object
* @param oid OID of the attribute
* @param value ASN.1 encoded value of the attribute
*/
void (*set_attribute) (pkcs9_t *this, int oid, chunk_t value);
/**
- * @brief gets a PKCS#9 messageDigest attribute
+ * Gets a PKCS#9 messageDigest attribute
*
- * @param this calling object
* @return messageDigest
*/
chunk_t (*get_messageDigest) (pkcs9_t *this);
/**
- * @brief add a PKCS#9 messageDigest attribute
+ * Add a PKCS#9 messageDigest attribute
*
- * @param this calling object
* @param value messageDigest
*/
void (*set_messageDigest) (pkcs9_t *this, chunk_t value);
/**
- * @brief Destroys the PKCS#9 attribute list.
- *
- * @param this PKCS#9 attribute list to destroy
+ * Destroys the PKCS#9 attribute list.
*/
void (*destroy) (pkcs9_t *this);
};
/**
- * @brief Read a PKCS#9 attribute list from a DER encoded chunk.
+ * Read a PKCS#9 attribute list from a DER encoded chunk.
*
* @param chunk chunk containing DER encoded data
* @param level ASN.1 parsing start level
* @return created pkcs9 attribute list, or NULL if invalid.
- *
- * @ingroup crypto
*/
pkcs9_t *pkcs9_create_from_chunk(chunk_t chunk, u_int level);
/**
- * @brief Create an empty PKCS#9 attribute list
+ * Create an empty PKCS#9 attribute list
*
* @param chunk chunk containing data
* @return created pkcs9 attribute list.
- *
- * @ingroup crypto
*/
pkcs9_t *pkcs9_create(void);
-#endif /* _PKCS9_H */
+#endif /* PKCS9_H_ @} */
diff --git a/src/libstrongswan/crypto/prf_plus.c b/src/libstrongswan/crypto/prf_plus.c
index 6bd444b1f..de7dbff84 100644
--- a/src/libstrongswan/crypto/prf_plus.c
+++ b/src/libstrongswan/crypto/prf_plus.c
@@ -1,10 +1,3 @@
-/**
- * @file prf_plus.c
- *
- * @brief Implementation of prf_plus_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,8 @@
* 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.
+ *
+ * $Id: prf_plus.c 3589 2008-03-13 14:14:44Z martin $
*/
#include <string.h>
diff --git a/src/libstrongswan/crypto/prf_plus.h b/src/libstrongswan/crypto/prf_plus.h
index 90f9ce2eb..e63827858 100644
--- a/src/libstrongswan/crypto/prf_plus.h
+++ b/src/libstrongswan/crypto/prf_plus.h
@@ -1,10 +1,3 @@
-/**
- * @file prf_plus.h
- *
- * @brief Interface for prf_plus.h.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* 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.
+ *
+ * $Id: prf_plus.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup prf_plus prf_plus
+ * @{ @ingroup crypto
*/
#ifndef PRF_PLUS_H_
@@ -29,53 +29,43 @@ typedef struct prf_plus_t prf_plus_t;
#include <crypto/prfs/prf.h>
/**
- * @brief Implementation of the prf+ function described in IKEv2 RFC.
+ * Implementation of the prf+ function described in IKEv2 RFC.
*
* This class implements the prf+ algorithm. Internally it uses a pseudo random
* function, which implements the prf_t interface.
- *
* See IKEv2 RFC 2.13.
- *
- * @b Constructors:
- * - prf_plus_create()
- *
- * @ingroup transforms
*/
struct prf_plus_t {
/**
- * @brief Get pseudo random bytes.
+ * Get pseudo random bytes.
*
* Get the next few bytes of the prf+ output. Space
* must be allocated by the caller.
*
- * @param this calling object
- * @param length number of bytes to get
- * @param[out] buffer pointer where the generated bytes will be written
+ * @param length number of bytes to get
+ * @param buffer pointer where the generated bytes will be written
*/
void (*get_bytes) (prf_plus_t *this, size_t length, u_int8_t *buffer);
/**
- * @brief Allocate pseudo random bytes.
+ * Allocate pseudo random bytes.
*
* Get the next few bytes of the prf+ output. This function
* will allocate the required space.
*
- * @param this calling object
- * @param length number of bytes to get
- * @param[out] chunk chunk which will hold generated bytes
+ * @param length number of bytes to get
+ * @param chunk chunk which will hold generated bytes
*/
void (*allocate_bytes) (prf_plus_t *this, size_t length, chunk_t *chunk);
/**
- * @brief Destroys a prf_plus_t object.
- *
- * @param this calling object
+ * Destroys a prf_plus_t object.
*/
void (*destroy) (prf_plus_t *this);
};
/**
- * @brief Creates a new prf_plus_t object.
+ * Creates a new prf_plus_t object.
*
* Seed will be cloned. prf will
* not be cloned, must be destroyed outside after
@@ -84,9 +74,7 @@ struct prf_plus_t {
* @param prf prf object to use
* @param seed input seed for prf
* @return prf_plus_t object
- *
- * @ingroup transforms
*/
prf_plus_t *prf_plus_create(prf_t *prf, chunk_t seed);
-#endif /*PRF_PLUS_H_*/
+#endif /*PRF_PLUS_H_ @} */
diff --git a/src/libstrongswan/crypto/prfs/fips_prf.c b/src/libstrongswan/crypto/prfs/fips_prf.c
deleted file mode 100644
index 0ab80b089..000000000
--- a/src/libstrongswan/crypto/prfs/fips_prf.c
+++ /dev/null
@@ -1,258 +0,0 @@
-/**
- * @file fips_prf.c
- *
- * @brief Implementation for fips_prf_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#include "fips_prf.h"
-
-#include <arpa/inet.h>
-
-#include <debug.h>
-
-typedef struct private_fips_prf_t private_fips_prf_t;
-
-/**
- * Private data of a fips_prf_t object.
- */
-struct private_fips_prf_t {
- /**
- * Public fips_prf_t interface.
- */
- fips_prf_t public;
-
- /**
- * key of prf function, "b" long
- */
- u_int8_t *key;
-
- /**
- * size of "b" in bytes
- */
- size_t b;
-
- /**
- * G function, either SHA1 or DES
- */
- void (*g)(u_int8_t t[], chunk_t c, u_int8_t res[]);
-};
-
-/**
- * t used in G(), equals to initial SHA1 value
- */
-static u_int8_t t[] = {
- 0x67,0x45,0x23,0x01,0xEF,0xCD,0xAB,0x89,0x98,0xBA,
- 0xDC,0xFE,0x10,0x32,0x54,0x76,0xC3,0xD2,0xE1,0xF0,
-};
-
-/**
- * sum = (a + b) mod 2 ^ (length * 8)
- */
-static void add_mod(size_t length, u_int8_t a[], u_int8_t b[], u_int8_t sum[])
-{
- int i, c = 0;
-
- for(i = length - 1; i >= 0; i--)
- {
- u_int32_t tmp;
-
- tmp = a[i] + b[i] + c;
- sum[i] = 0xff & tmp;
- c = tmp >> 8;
- }
-}
-
-/**
- * calculate "chunk mod 2^(length*8)" and save it into buffer
- */
-static void chunk_mod(size_t length, chunk_t chunk, u_int8_t buffer[])
-{
- if (chunk.len < length)
- {
- /* apply seed as least significant bits, others are zero */
- memset(buffer, 0, length - chunk.len);
- memcpy(buffer + length - chunk.len, chunk.ptr, chunk.len);
- }
- else
- {
- /* use least significant bytes from seed, as we use mod 2^b */
- memcpy(buffer, chunk.ptr + chunk.len - length, length);
- }
-}
-
-/**
- * Implementation of prf_t.get_bytes.
- *
- * Test vector:
- *
- * key:
- * 0xbd, 0x02, 0x9b, 0xbe, 0x7f, 0x51, 0x96, 0x0b,
- * 0xcf, 0x9e, 0xdb, 0x2b, 0x61, 0xf0, 0x6f, 0x0f,
- * 0xeb, 0x5a, 0x38, 0xb6
- *
- * seed:
- * 0x00
- *
- * result:
- * 0x20, 0x70, 0xb3, 0x22, 0x3d, 0xba, 0x37, 0x2f,
- * 0xde, 0x1c, 0x0f, 0xfc, 0x7b, 0x2e, 0x3b, 0x49,
- * 0x8b, 0x26, 0x06, 0x14, 0x3c, 0x6c, 0x18, 0xba,
- * 0xcb, 0x0f, 0x6c, 0x55, 0xba, 0xbb, 0x13, 0x78,
- * 0x8e, 0x20, 0xd7, 0x37, 0xa3, 0x27, 0x51, 0x16
- */
-static void get_bytes(private_fips_prf_t *this, chunk_t seed, u_int8_t w[])
-{
- int i;
- u_int8_t xval[this->b];
- u_int8_t xseed[this->b];
- u_int8_t sum[this->b];
- u_int8_t *xkey = this->key;
- u_int8_t one[this->b];
- chunk_t xval_chunk = chunk_from_buf(xval);
-
- memset(one, 0, this->b);
- one[this->b - 1] = 0x01;
-
- /* 3.1 */
- chunk_mod(this->b, seed, xseed);
-
- /* 3.2 */
- for (i = 0; i < 2; i++) /* twice */
- {
- /* a. XVAL = (XKEY + XSEED j) mod 2^b */
- add_mod(this->b, xkey, xseed, xval);
- DBG3("XVAL %b", xval, this->b);
- /* b. wi = G(t, XVAL ) */
- this->g(t, xval_chunk, &w[i * this->b]);
- DBG3("w[%d] %b", i, &w[i * this->b], this->b);
- /* c. XKEY = (1 + XKEY + wi) mod 2b */
- add_mod(this->b, xkey, &w[i * this->b], sum);
- add_mod(this->b, sum, one, xkey);
- DBG3("XKEY %b", xkey, this->b);
- }
-
- /* 3.3 done already, mod q not used */
-}
-
-/**
- * Implementation of prf_t.get_block_size.
- */
-static size_t get_block_size(private_fips_prf_t *this)
-{
- return 2 * this->b;
-}
-/**
- * Implementation of prf_t.allocate_bytes.
- */
-static void allocate_bytes(private_fips_prf_t *this, chunk_t seed, chunk_t *chunk)
-{
- *chunk = chunk_alloc(get_block_size(this));
- get_bytes(this, seed, chunk->ptr);
-}
-
-/**
- * Implementation of prf_t.get_key_size.
- */
-static size_t get_key_size(private_fips_prf_t *this)
-{
- return this->b;
-}
-
-/**
- * Implementation of prf_t.set_key.
- */
-static void set_key(private_fips_prf_t *this, chunk_t key)
-{
- /* save key as "key mod 2^b" */
- chunk_mod(this->b, key, this->key);
-}
-
-/**
- * Implementation of the G() function based on SHA1
- */
-void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[])
-{
- hasher_t *hasher;
- u_int8_t buf[64];
- chunk_t state_chunk;
- u_int32_t *state, *iv, *hash;
-
- if (c.len < sizeof(buf))
- {
- /* pad c with zeros */
- memset(buf, 0, sizeof(buf));
- memcpy(buf, c.ptr, c.len);
- c.ptr = buf;
- c.len = sizeof(buf);
- }
- else
- {
- /* not more than 512 bits can be G()-ed */
- c.len = sizeof(buf);
- }
-
- /* our SHA1 hasher's state is 32-Bit integers in host order. We must
- * convert them */
- hasher = hasher_create(HASH_SHA1);
- state_chunk = hasher->get_state(hasher);
- state = (u_int32_t*)state_chunk.ptr;
- iv = (u_int32_t*)t;
- hash = (u_int32_t*)res;
- state[0] = htonl(iv[0]);
- state[1] = htonl(iv[1]);
- state[2] = htonl(iv[2]);
- state[3] = htonl(iv[3]);
- hasher->get_hash(hasher, c, NULL);
- hash[0] = htonl(state[0]);
- hash[1] = htonl(state[1]);
- hash[2] = htonl(state[2]);
- hash[3] = htonl(state[3]);
- hash[4] = htonl(state[4]);
- hasher->destroy(hasher);
-}
-
-/**
- * Implementation of prf_t.destroy.
- */
-static void destroy(private_fips_prf_t *this)
-{
- free(this->key);
- free(this);
-}
-
-/*
- * Described in header.
- */
-fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]))
-{
- private_fips_prf_t *this = malloc_thing(private_fips_prf_t);
-
- this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
- this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
- this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
- this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
- this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
- this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
-
- this->g = g;
- this->b = b;
- this->key = malloc(b);
-
- return &(this->public);
-}
diff --git a/src/libstrongswan/crypto/prfs/fips_prf.h b/src/libstrongswan/crypto/prfs/fips_prf.h
deleted file mode 100644
index 283ee1f61..000000000
--- a/src/libstrongswan/crypto/prfs/fips_prf.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/**
- * @file fips_prf.h
- *
- * @brief Interface of fips_prf_t.
- *
- */
-
-/*
- * Copyright (C) 2006 Martin Willi
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef FIPS_PRF_H_
-#define FIPS_PRF_H_
-
-typedef struct fips_prf_t fips_prf_t;
-
-#include <library.h>
-#include <crypto/prfs/prf.h>
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief Implementation of prf_t using the FIPS 186-2-change1 standard.
- *
- * FIPS defines a "General Purpose Random Number Generator" (Revised
- * Algorithm for Computing m values of x (Appendix 3.1 of FIPS 186-2)). This
- * implementation is not intended for private key generation and therefore does
- * not include the "mod q" operation (see FIPS 186-2-change1 p74).
- * The FIPS PRF is stateful; the key changes every time when bytes are acquired.
- *
- * @b Constructors:
- * - fips_prf_create()
- * - prf_create() using one of the FIPS algorithms
- *
- * @ingroup prfs
- */
-struct fips_prf_t {
-
- /**
- * Generic prf_t interface for this fips_prf_t class.
- */
- prf_t prf_interface;
-};
-
-/**
- * @brief Creates a new fips_prf_t object.
- *
- * FIPS 186-2 defines G() functions used in the PRF function. It can
- * be implemented either based on SHA1 or DES.
- *
- * @param b size of b (in bytes, not bits)
- * @param g G() function to use (e.g. g_sha1)
- * @return
- * - fips_prf_t object
- * - NULL if b invalid not supported
- *
- * @ingroup prfs
- */
-fips_prf_t *fips_prf_create(size_t b, void(*g)(u_int8_t[],chunk_t,u_int8_t[]));
-
-/**
- * @brief Implementation of the G() function based on SHA1.
- *
- * @param t initialization vector for SHA1 hasher, 20 bytes long
- * @param c value to hash, not longer than 512 bit
- * @param res result of G(), requries 20 bytes
- */
-void g_sha1(u_int8_t t[], chunk_t c, u_int8_t res[]);
-
-#endif /* FIPS_PRF_H_ */
diff --git a/src/libstrongswan/crypto/prfs/hmac_prf.c b/src/libstrongswan/crypto/prfs/hmac_prf.c
deleted file mode 100644
index f315f880d..000000000
--- a/src/libstrongswan/crypto/prfs/hmac_prf.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/**
- * @file hmac_prf.c
- *
- * @brief Implementation for hmac_prf_t.
- *
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#include "hmac_prf.h"
-
-#include <crypto/hmac.h>
-
-
-typedef struct private_hmac_prf_t private_hmac_prf_t;
-
-/**
- * Private data of a hma_prf_t object.
- */
-struct private_hmac_prf_t {
- /**
- * Public hmac_prf_t interface.
- */
- hmac_prf_t public;
-
- /**
- * Hmac to use for generation.
- */
- hmac_t *hmac;
-};
-
-/**
- * Implementation of prf_t.get_bytes.
- */
-static void get_bytes(private_hmac_prf_t *this, chunk_t seed, u_int8_t *buffer)
-{
- this->hmac->get_mac(this->hmac, seed, buffer);
-}
-
-/**
- * Implementation of prf_t.allocate_bytes.
- */
-static void allocate_bytes(private_hmac_prf_t *this, chunk_t seed, chunk_t *chunk)
-{
- this->hmac->allocate_mac(this->hmac, seed, chunk);
-}
-
-/**
- * Implementation of prf_t.get_block_size.
- */
-static size_t get_block_size(private_hmac_prf_t *this)
-{
- return this->hmac->get_block_size(this->hmac);
-}
-
-/**
- * Implementation of prf_t.get_block_size.
- */
-static size_t get_key_size(private_hmac_prf_t *this)
-{
- /* for HMAC prfs, IKEv2 uses block size as key size */
- return this->hmac->get_block_size(this->hmac);
-}
-
-/**
- * Implementation of prf_t.set_key.
- */
-static void set_key(private_hmac_prf_t *this, chunk_t key)
-{
- this->hmac->set_key(this->hmac, key);
-}
-
-/**
- * Implementation of prf_t.destroy.
- */
-static void destroy(private_hmac_prf_t *this)
-{
- this->hmac->destroy(this->hmac);
- free(this);
-}
-
-/*
- * Described in header.
- */
-hmac_prf_t *hmac_prf_create(hash_algorithm_t hash_algorithm)
-{
- private_hmac_prf_t *this = malloc_thing(private_hmac_prf_t);
-
- this->public.prf_interface.get_bytes = (void (*) (prf_t *,chunk_t,u_int8_t*))get_bytes;
- this->public.prf_interface.allocate_bytes = (void (*) (prf_t*,chunk_t,chunk_t*))allocate_bytes;
- this->public.prf_interface.get_block_size = (size_t (*) (prf_t*))get_block_size;
- this->public.prf_interface.get_key_size = (size_t (*) (prf_t*))get_key_size;
- this->public.prf_interface.set_key = (void (*) (prf_t *,chunk_t))set_key;
- this->public.prf_interface.destroy = (void (*) (prf_t *))destroy;
-
- this->hmac = hmac_create(hash_algorithm);
- if (this->hmac == NULL)
- {
- free(this);
- return NULL;
- }
-
- return &(this->public);
-}
diff --git a/src/libstrongswan/crypto/prfs/hmac_prf.h b/src/libstrongswan/crypto/prfs/hmac_prf.h
deleted file mode 100644
index 9b06ee3a2..000000000
--- a/src/libstrongswan/crypto/prfs/hmac_prf.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * @file hmac_prf.h
- *
- * @brief Interface of hmac_prf_t.
- *
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef PRF_HMAC_H_
-#define PRF_HMAC_H_
-
-typedef struct hmac_prf_t hmac_prf_t;
-
-#include <library.h>
-#include <crypto/prfs/prf.h>
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief Implementation of prf_t interface using the
- * HMAC algorithm.
- *
- * This simply wraps a hmac_t in a prf_t. More a question of
- * interface matching.
- *
- * @b Constructors:
- * - hmac_prf_create()
- *
- * @ingroup prfs
- */
-struct hmac_prf_t {
-
- /**
- * Generic prf_t interface for this hmac_prf_t class.
- */
- prf_t prf_interface;
-};
-
-/**
- * @brief Creates a new hmac_prf_t object.
- *
- * @param hash_algorithm hmac's hash algorithm
- * @return
- * - hmac_prf_t object
- * - NULL if hash not supported
- *
- * @ingroup prfs
- */
-hmac_prf_t *hmac_prf_create(hash_algorithm_t hash_algorithm);
-
-#endif /*PRF_HMAC_SHA1_H_*/
diff --git a/src/libstrongswan/crypto/prfs/prf.c b/src/libstrongswan/crypto/prfs/prf.c
index f803829af..812f6278d 100644
--- a/src/libstrongswan/crypto/prfs/prf.c
+++ b/src/libstrongswan/crypto/prfs/prf.c
@@ -1,10 +1,3 @@
-/**
- * @file prf.c
- *
- * @brief Generic constructor for all prf_t
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,20 +12,18 @@
* 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.
+ *
+ * $Id: prf.c 3619 2008-03-19 14:02:52Z martin $
*/
-
#include "prf.h"
-#include <crypto/hashers/hasher.h>
-#include <crypto/prfs/hmac_prf.h>
-#include <crypto/prfs/fips_prf.h>
-
-ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_FIPS_DES,
+ENUM_BEGIN(pseudo_random_function_names, PRF_UNDEFINED, PRF_KEYED_SHA1,
"PRF_UNDEFINED",
"PRF_FIPS_SHA1_160",
- "PRF_FIPS_DES");
-ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_FIPS_DES,
+ "PRF_FIPS_DES",
+ "PRF_KEYED_SHA1");
+ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_KEYED_SHA1,
"PRF_HMAC_MD5",
"PRF_HMAC_SHA1",
"PRF_HMAC_TIGER",
@@ -42,29 +33,3 @@ ENUM_NEXT(pseudo_random_function_names, PRF_HMAC_MD5, PRF_HMAC_SHA2_512, PRF_FIP
"PRF_HMAC_SHA2_512");
ENUM_END(pseudo_random_function_names, PRF_HMAC_SHA2_512);
-/*
- * Described in header.
- */
-prf_t *prf_create(pseudo_random_function_t pseudo_random_function)
-{
- switch (pseudo_random_function)
- {
- case PRF_HMAC_SHA1:
- return (prf_t*)hmac_prf_create(HASH_SHA1);
- case PRF_HMAC_MD5:
- return (prf_t*)hmac_prf_create(HASH_MD5);
- case PRF_HMAC_SHA2_256:
- return (prf_t*)hmac_prf_create(HASH_SHA256);
- case PRF_HMAC_SHA2_384:
- return (prf_t*)hmac_prf_create(HASH_SHA384);
- case PRF_HMAC_SHA2_512:
- return (prf_t*)hmac_prf_create(HASH_SHA512);
- case PRF_FIPS_SHA1_160:
- return (prf_t*)fips_prf_create(20, g_sha1);
- case PRF_FIPS_DES:
- case PRF_HMAC_TIGER:
- case PRF_AES128_CBC:
- default:
- return NULL;
- }
-}
diff --git a/src/libstrongswan/crypto/prfs/prf.h b/src/libstrongswan/crypto/prfs/prf.h
index 8560a4a9c..324eb89b4 100644
--- a/src/libstrongswan/crypto/prfs/prf.h
+++ b/src/libstrongswan/crypto/prfs/prf.h
@@ -1,10 +1,3 @@
-/**
- * @file prf.h
- *
- * @brief Interface prf_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* 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.
+ *
+ * $Id: prf.h 3916 2008-05-08 12:43:27Z martin $
+ */
+
+/**
+ * @defgroup prf prf
+ * @{ @ingroup crypto
*/
#ifndef PRF_H_
@@ -30,12 +30,10 @@ typedef struct prf_t prf_t;
#include <library.h>
/**
- * @brief Pseudo random function, as in IKEv2 RFC 3.3.2.
+ * Pseudo random function, as in IKEv2 RFC 3.3.2.
*
* PRF algorithms not defined in IKEv2 are allocated in "private use"
* space.
- *
- * @ingroup prfs
*/
enum pseudo_random_function_t {
PRF_UNDEFINED = 1024,
@@ -44,7 +42,7 @@ enum pseudo_random_function_t {
/** Implemented via hmac_prf_t. */
PRF_HMAC_SHA1 = 2,
PRF_HMAC_TIGER = 3,
- PRF_AES128_CBC = 4,
+ PRF_AES128_XCBC = 4,
/** Implemented via hmac_prf_t. */
PRF_HMAC_SHA2_256 = 5,
/** Implemented via hmac_prf_t. */
@@ -55,6 +53,11 @@ enum pseudo_random_function_t {
PRF_FIPS_SHA1_160 = 1025,
/** Could be implemented via fips_prf_t, uses fixed output size of 160bit */
PRF_FIPS_DES = 1026,
+ /**
+ * Keyed hash algorithm using SHA1, used in EAP-AKA:
+ * This PRF uses SHA1, but XORs the key into the IV. No "Final()" operation
+ * is applied to the SHA1 state. */
+ PRF_KEYED_SHA1 = 1027,
};
/**
@@ -63,80 +66,53 @@ enum pseudo_random_function_t {
extern enum_name_t *pseudo_random_function_names;
/**
- * @brief Generic interface for pseudo-random-functions.
- *
- * @b Constructors:
- * - prf_create()
- * - hmac_prf_create()
- *
- * @todo Implement more prf algorithms
- *
- * @ingroup prfs
+ * Generic interface for pseudo-random-functions.
*/
struct prf_t {
/**
- * @brief Generates pseudo random bytes and writes them in the buffer.
+ * Generates pseudo random bytes and writes them in the buffer.
*
- * @param this calling object
- * @param seed a chunk containing the seed for the next bytes
- * @param[out] buffer pointer where the generated bytes will be written
+ * @param seed a chunk containing the seed for the next bytes
+ * @param buffer pointer where the generated bytes will be written
*/
void (*get_bytes) (prf_t *this, chunk_t seed, u_int8_t *buffer);
/**
- * @brief Generates pseudo random bytes and allocate space for them.
+ * Generates pseudo random bytes and allocate space for them.
*
- * @param this calling object
- * @param seed a chunk containing the seed for the next bytes
- * @param[out] chunk chunk which will hold generated bytes
+ * @param seed a chunk containing the seed for the next bytes
+ * @param chunk chunk which will hold generated bytes
*/
void (*allocate_bytes) (prf_t *this, chunk_t seed, chunk_t *chunk);
/**
- * @brief Get the block size of this prf_t object.
+ * Get the block size of this prf_t object.
*
- * @param this calling object
- * @return block size in bytes
+ * @return block size in bytes
*/
size_t (*get_block_size) (prf_t *this);
/**
- * @brief Get the key size of this prf_t object.
+ * Get the key size of this prf_t object.
*
* This is a suggestion only, all implemented PRFs accept variable key
* length.
*
- * @param this calling object
- * @return key size in bytes
+ * @return key size in bytes
*/
size_t (*get_key_size) (prf_t *this);
/**
- * @brief Set the key for this prf_t object.
+ * Set the key for this prf_t object.
*
- * @param this calling object
- * @param key key to set
+ * @param key key to set
*/
void (*set_key) (prf_t *this, chunk_t key);
/**
- * @brief Destroys a prf object.
- *
- * @param this calling object
+ * Destroys a prf object.
*/
void (*destroy) (prf_t *this);
};
-/**
- * @brief Generic constructor for a prf_t oject.
- *
- * @param pseudo_random_function Algorithm to use
- * @return
- * - prf_t object
- * - NULL if prf algorithm not supported
- *
- * @ingroup prfs
- */
-prf_t *prf_create(pseudo_random_function_t pseudo_random_function);
-
-#endif /*PRF_H_*/
+#endif /*PRF_H_ @} */
diff --git a/src/libstrongswan/crypto/rngs/rng.c b/src/libstrongswan/crypto/rngs/rng.c
new file mode 100644
index 000000000..435e043e8
--- /dev/null
+++ b/src/libstrongswan/crypto/rngs/rng.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ *
+ * $Id$
+ */
+
+#include "rng.h"
+
+ENUM(rng_quality_names, RNG_WEAK, RNG_REAL,
+ "RNG_WEAK",
+ "RNG_STRONG",
+ "RNG_REAL",
+);
diff --git a/src/libstrongswan/crypto/rngs/rng.h b/src/libstrongswan/crypto/rngs/rng.h
new file mode 100644
index 000000000..08f7af209
--- /dev/null
+++ b/src/libstrongswan/crypto/rngs/rng.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2008 Martin Willi
+ * Hochschule fuer Technik Rapperswil
+ *
+ * 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 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * 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.
+ *
+ * $Id: rng.h 3619 2008-03-19 14:02:52Z martin $
+ */
+
+/**
+ * @defgroup rng rng
+ * @{ @ingroup crypto
+ */
+
+#ifndef RNG_H_
+#define RNG_H_
+
+typedef enum rng_quality_t rng_quality_t;
+typedef struct rng_t rng_t;
+
+#include <library.h>
+
+/**
+ * Quality of generated random bytes.
+ */
+enum rng_quality_t {
+ /** weak randomness, usable for nonces, IVs */
+ RNG_WEAK,
+ /** stronger randomness, usable for session keys */
+ RNG_STRONG,
+ /** real random, key material */
+ RNG_REAL,
+};
+
+/**
+ * enum name for rng_quality_t.
+ */
+extern enum_name_t *rng_quality_names;
+
+/**
+ * Generic interface for random number generators.
+ */
+struct rng_t {
+
+ /**
+ * Generates random bytes and writes them in the buffer.
+ *
+ * @param len number of bytes to get
+ * @param buffer pointer where the generated bytes will be written
+ */
+ void (*get_bytes) (rng_t *this, u_int len, u_int8_t *buffer);
+
+ /**
+ * Generates random bytes and allocate space for them.
+ *
+ * @param len number of bytes to get
+ * @param chunk chunk which will hold generated bytes
+ */
+ void (*allocate_bytes) (rng_t *this, u_int len, chunk_t *chunk);
+
+ /**
+ * Destroys a rng object.
+ */
+ void (*destroy) (rng_t *this);
+};
+
+#endif /*RNG_H_ @} */
diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.c b/src/libstrongswan/crypto/rsa/rsa_private_key.c
deleted file mode 100644
index 1b1499887..000000000
--- a/src/libstrongswan/crypto/rsa/rsa_private_key.c
+++ /dev/null
@@ -1,722 +0,0 @@
-/**
- * @file rsa_private_key.c
- *
- * @brief Implementation of rsa_private_key_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: rsa_private_key.c 3429 2008-01-27 20:59:22Z andreas $
- */
-
-#include <gmp.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-
-#include "rsa_public_key.h"
-#include "rsa_private_key.h"
-
-#include <debug.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <utils/randomizer.h>
-
-/**
- * defined in rsa_public_key.c
- */
-extern chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e);
-extern chunk_t rsa_public_key_id_create(const mpz_t n, const mpz_t e);
-
-/**
- * Public exponent to use for key generation.
- */
-#define PUBLIC_EXPONENT 0x10001
-
-typedef struct private_rsa_private_key_t private_rsa_private_key_t;
-
-/**
- * Private data of a rsa_private_key_t object.
- */
-struct private_rsa_private_key_t {
- /**
- * Public interface for this signer.
- */
- rsa_private_key_t public;
-
- /**
- * Version of key, as encoded in PKCS#1
- */
- u_int version;
-
- /**
- * Public modulus.
- */
- mpz_t n;
-
- /**
- * Public exponent.
- */
- mpz_t e;
-
- /**
- * Private prime 1.
- */
- mpz_t p;
-
- /**
- * Private Prime 2.
- */
- mpz_t q;
-
- /**
- * Private exponent.
- */
- mpz_t d;
-
- /**
- * Private exponent 1.
- */
- mpz_t exp1;
-
- /**
- * Private exponent 2.
- */
- mpz_t exp2;
-
- /**
- * Private coefficient.
- */
- mpz_t coeff;
-
- /**
- * Keysize in bytes.
- */
- size_t k;
-
- /**
- * Keyid formed as a SHA-1 hash of a publicKeyInfo object
- */
- chunk_t keyid;
-
- /**
- * @brief Implements the RSADP algorithm specified in PKCS#1.
- *
- * @param this calling object
- * @param data data to process
- * @return processed data
- */
- chunk_t (*rsadp) (private_rsa_private_key_t *this, chunk_t data);
-
- /**
- * @brief Implements the RSASP1 algorithm specified in PKCS#1.
- * @param this calling object
- * @param data data to process
- * @return processed data
- */
- chunk_t (*rsasp1) (private_rsa_private_key_t *this, chunk_t data);
-};
-
-/* ASN.1 definition of a PKCS#1 RSA private key */
-static const asn1Object_t privkey_objects[] = {
- { 0, "RSAPrivateKey", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "version", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 2 */
- { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 1, "privateExponent", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 1, "prime1", ASN1_INTEGER, ASN1_BODY }, /* 5 */
- { 1, "prime2", ASN1_INTEGER, ASN1_BODY }, /* 6 */
- { 1, "exponent1", ASN1_INTEGER, ASN1_BODY }, /* 7 */
- { 1, "exponent2", ASN1_INTEGER, ASN1_BODY }, /* 8 */
- { 1, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 9 */
- { 1, "otherPrimeInfos", ASN1_SEQUENCE, ASN1_OPT |
- ASN1_LOOP }, /* 10 */
- { 2, "otherPrimeInfo", ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
- { 3, "prime", ASN1_INTEGER, ASN1_BODY }, /* 12 */
- { 3, "exponent", ASN1_INTEGER, ASN1_BODY }, /* 13 */
- { 3, "coefficient", ASN1_INTEGER, ASN1_BODY }, /* 14 */
- { 1, "end opt or loop", ASN1_EOC, ASN1_END } /* 15 */
-};
-
-#define PRIV_KEY_VERSION 1
-#define PRIV_KEY_MODULUS 2
-#define PRIV_KEY_PUB_EXP 3
-#define PRIV_KEY_PRIV_EXP 4
-#define PRIV_KEY_PRIME1 5
-#define PRIV_KEY_PRIME2 6
-#define PRIV_KEY_EXP1 7
-#define PRIV_KEY_EXP2 8
-#define PRIV_KEY_COEFF 9
-#define PRIV_KEY_ROOF 16
-
-/**
- * Auxiliary function overwriting private key material with
- * pseudo-random bytes before releasing it
- */
-static void mpz_clear_randomized(mpz_t z)
-{
- size_t len = mpz_size(z) * GMP_LIMB_BITS / BITS_PER_BYTE;
- u_int8_t *random_bytes = alloca(len);
-
- randomizer_t *randomizer = randomizer_create();
-
- randomizer->get_pseudo_random_bytes(randomizer, len, random_bytes);
-
- /* overwrite mpz_t with pseudo-random bytes before clearing it */
- mpz_import(z, len, 1, 1, 1, 0, random_bytes);
- mpz_clear(z);
-
- randomizer->destroy(randomizer);
-}
-
-/**
- * Generate a random prime number with prime_len bytes
- */
-static status_t compute_prime(private_rsa_private_key_t *this, size_t prime_len, mpz_t *prime)
-{
- randomizer_t *randomizer;
- chunk_t random_bytes;
- status_t status;
-
- randomizer = randomizer_create();
- mpz_init(*prime);
-
- do
- {
- DBG1(" generating %d bit prime from %s ...", BITS_PER_BYTE * prime_len, DEV_RANDOM);
- status = randomizer->allocate_random_bytes(randomizer, prime_len, &random_bytes);
- if (status != SUCCESS)
- {
- randomizer->destroy(randomizer);
- mpz_clear(*prime);
- return FAILED;
- }
-
- /* make sure most significant bit is set */
- random_bytes.ptr[0] = random_bytes.ptr[0] | 0x80;
-
- /* convert chunk to mpz value */
- mpz_import(*prime, random_bytes.len, 1, 1, 1, 0, random_bytes.ptr);
-
- /* get next prime */
- mpz_nextprime (*prime, *prime);
-
- /* free the random_bytes after overwriting them with a pseudo-random sequence */
- chunk_free_randomized(&random_bytes);
- }
- /* check if it isnt too large */
- while (((mpz_sizeinbase(*prime, 2) + 7) / BITS_PER_BYTE) > prime_len);
-
- randomizer->destroy(randomizer);
- return SUCCESS;
-}
-
-/**
- * Implementation of private_rsa_private_key_t.rsadp and private_rsa_private_key_t.rsasp1.
- */
-static chunk_t rsadp(private_rsa_private_key_t *this, chunk_t data)
-{
- mpz_t t1, t2;
- chunk_t decrypted;
-
- mpz_init(t1);
- mpz_init(t2);
-
- mpz_import(t1, data.len, 1, 1, 1, 0, data.ptr);
-
- mpz_powm(t2, t1, this->exp1, this->p); /* m1 = c^dP mod p */
- mpz_powm(t1, t1, this->exp2, this->q); /* m2 = c^dQ mod Q */
- mpz_sub(t2, t2, t1); /* h = qInv (m1 - m2) mod p */
- mpz_mod(t2, t2, this->p);
- mpz_mul(t2, t2, this->coeff);
- mpz_mod(t2, t2, this->p);
-
- mpz_mul(t2, t2, this->q); /* m = m2 + h q */
- mpz_add(t1, t1, t2);
-
- decrypted.len = this->k;
- decrypted.ptr = mpz_export(NULL, NULL, 1, decrypted.len, 1, 0, t1);
-
- mpz_clear_randomized(t1);
- mpz_clear_randomized(t2);
-
- return decrypted;
-}
-
-/**
- * Implementation of rsa_private_key_t.pkcs1_decrypt.
- */
-static status_t pkcs1_decrypt(private_rsa_private_key_t *this,
- chunk_t in, chunk_t *out)
-{
- status_t status = FAILED;
- chunk_t em, em_ori;
-
- /* decrypt the input data */
- em = em_ori = this->rsadp(this, in);
-
- /* PKCS#1 v1.5 EME encryption formatting
- * EM = 00 || 02 || PS || 00 || M
- * PS = pseudo-random nonzero octets
- */
-
- /* check for magic bytes */
- if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x02)
- {
- DBG1("incorrect padding - probably wrong RSA key");
- goto end;
- }
- em.ptr += 2;
- em.len -= 2;
-
- /* the plaintext data starts after first 0x00 byte */
- while (em.len-- > 0 && *em.ptr++ != 0x00);
-
- if (em.len == 0)
- {
- DBG1("no plaintext data found");
- goto end;
- }
-
- *out = chunk_clone(em);
- status = SUCCESS;
-
-end:
- free(em_ori.ptr);
- return status;
-}
-
-/**
- * Implementation of rsa_private_key_t.build_emsa_pkcs1_signature.
- */
-static status_t build_emsa_pkcs1_signature(private_rsa_private_key_t *this,
- hash_algorithm_t hash_algorithm,
- chunk_t data, chunk_t *signature)
-{
- hasher_t *hasher;
- chunk_t em, digestInfo, hash;
- int hash_oid = hasher_algorithm_to_oid(hash_algorithm);
-
- if (hash_oid == OID_UNKNOWN)
- {
- return NOT_SUPPORTED;
- }
-
- /* get hasher */
- hasher = hasher_create(hash_algorithm);
- if (hasher == NULL)
- {
- return NOT_SUPPORTED;
- }
-
- /* build hash */
- hasher->allocate_hash(hasher, data, &hash);
- hasher->destroy(hasher);
-
- /* build DER-encoded digestInfo */
- digestInfo = asn1_wrap(ASN1_SEQUENCE, "cm",
- asn1_algorithmIdentifier(hash_oid),
- asn1_simple_object(ASN1_OCTET_STRING, hash)
- );
- chunk_free(&hash);
-
- /* build chunk to rsa-decrypt:
- * EM = 0x00 || 0x01 || PS || 0x00 || T.
- * PS = 0xFF padding, with length to fill em
- * T = encoded_hash
- */
- em.len = this->k;
- em.ptr = malloc(em.len);
-
- /* fill em with padding */
- memset(em.ptr, 0xFF, em.len);
- /* set magic bytes */
- *(em.ptr) = 0x00;
- *(em.ptr+1) = 0x01;
- *(em.ptr + em.len - digestInfo.len - 1) = 0x00;
- /* set DER-encoded hash */
- memcpy(em.ptr + em.len - digestInfo.len, digestInfo.ptr, digestInfo.len);
-
- /* build signature */
- *signature = this->rsasp1(this, em);
-
- free(digestInfo.ptr);
- free(em.ptr);
-
- return SUCCESS;
-}
-
-/**
- * Implementation of rsa_private_key_t.pkcs1_write.
- */
-static bool pkcs1_write(private_rsa_private_key_t *this, const char *filename, bool force)
-{
- bool status;
-
- chunk_t pkcs1 = asn1_wrap(ASN1_SEQUENCE, "cmmmmmmmm",
- ASN1_INTEGER_0,
- asn1_integer_from_mpz(this->n),
- asn1_integer_from_mpz(this->e),
- asn1_integer_from_mpz(this->d),
- asn1_integer_from_mpz(this->p),
- asn1_integer_from_mpz(this->q),
- asn1_integer_from_mpz(this->exp1),
- asn1_integer_from_mpz(this->exp2),
- asn1_integer_from_mpz(this->coeff));
-
- status = chunk_write(pkcs1, filename, "pkcs1", 0066, force);
- chunk_free_randomized(&pkcs1);
- return status;
-}
-
-/**
- * Implementation of rsa_private_key_t.get_public_key.
- */
-rsa_public_key_t *get_public_key(private_rsa_private_key_t *this)
-{
- return rsa_public_key_create(this->n, this->e);
-}
-
-/**
- * Implementation of rsa_private_key.belongs_to.
- */
-static bool belongs_to(private_rsa_private_key_t *this, rsa_public_key_t *public)
-{
- return chunk_equals(this->keyid, public->get_keyid(public));
-}
-
-/**
- * Check the loaded key if it is valid and usable
- * TODO: Log errors
- */
-static status_t check(private_rsa_private_key_t *this)
-{
- mpz_t t, u, q1;
- status_t status = SUCCESS;
-
- /* PKCS#1 1.5 section 6 requires modulus to have at least 12 octets.
- * We actually require more (for security).
- */
- if (this->k < 512 / BITS_PER_BYTE)
- {
- return FAILED;
- }
-
- /* we picked a max modulus size to simplify buffer allocation */
- if (this->k > 8192 / BITS_PER_BYTE)
- {
- return FAILED;
- }
-
- mpz_init(t);
- mpz_init(u);
- mpz_init(q1);
-
- /* check that n == p * q */
- mpz_mul(u, this->p, this->q);
- if (mpz_cmp(u, this->n) != 0)
- {
- status = FAILED;
- }
-
- /* check that e divides neither p-1 nor q-1 */
- mpz_sub_ui(t, this->p, 1);
- mpz_mod(t, t, this->e);
- if (mpz_cmp_ui(t, 0) == 0)
- {
- status = FAILED;
- }
-
- mpz_sub_ui(t, this->q, 1);
- mpz_mod(t, t, this->e);
- if (mpz_cmp_ui(t, 0) == 0)
- {
- status = FAILED;
- }
-
- /* check that d is e^-1 (mod lcm(p-1, q-1)) */
- /* see PKCS#1v2, aka RFC 2437, for the "lcm" */
- mpz_sub_ui(q1, this->q, 1);
- mpz_sub_ui(u, this->p, 1);
- mpz_gcd(t, u, q1); /* t := gcd(p-1, q-1) */
- mpz_mul(u, u, q1); /* u := (p-1) * (q-1) */
- mpz_divexact(u, u, t); /* u := lcm(p-1, q-1) */
-
- mpz_mul(t, this->d, this->e);
- mpz_mod(t, t, u);
- if (mpz_cmp_ui(t, 1) != 0)
- {
- status = FAILED;
- }
-
- /* check that exp1 is d mod (p-1) */
- mpz_sub_ui(u, this->p, 1);
- mpz_mod(t, this->d, u);
- if (mpz_cmp(t, this->exp1) != 0)
- {
- status = FAILED;
- }
-
- /* check that exp2 is d mod (q-1) */
- mpz_sub_ui(u, this->q, 1);
- mpz_mod(t, this->d, u);
- if (mpz_cmp(t, this->exp2) != 0)
- {
- status = FAILED;
- }
-
- /* check that coeff is (q^-1) mod p */
- mpz_mul(t, this->coeff, this->q);
- mpz_mod(t, t, this->p);
- if (mpz_cmp_ui(t, 1) != 0)
- {
- status = FAILED;
- }
-
- mpz_clear_randomized(t);
- mpz_clear_randomized(u);
- mpz_clear_randomized(q1);
- return status;
-}
-
-/**
- * Implementation of rsa_private_key.destroy.
- */
-static void destroy(private_rsa_private_key_t *this)
-{
- mpz_clear_randomized(this->n);
- mpz_clear_randomized(this->e);
- mpz_clear_randomized(this->p);
- mpz_clear_randomized(this->q);
- mpz_clear_randomized(this->d);
- mpz_clear_randomized(this->exp1);
- mpz_clear_randomized(this->exp2);
- mpz_clear_randomized(this->coeff);
- chunk_free_randomized(&this->keyid);
- free(this);
-}
-
-/**
- * Internal generic constructor
- */
-static private_rsa_private_key_t *rsa_private_key_create_empty(void)
-{
- private_rsa_private_key_t *this = malloc_thing(private_rsa_private_key_t);
-
- /* public functions */
- this->public.pkcs1_decrypt = (status_t (*) (rsa_private_key_t*,chunk_t,chunk_t*))pkcs1_decrypt;
- this->public.build_emsa_pkcs1_signature = (status_t (*) (rsa_private_key_t*,hash_algorithm_t,chunk_t,chunk_t*))build_emsa_pkcs1_signature;
- this->public.pkcs1_write = (bool (*) (rsa_private_key_t*,const char*,bool))pkcs1_write;
- this->public.get_public_key = (rsa_public_key_t* (*) (rsa_private_key_t*))get_public_key;
- this->public.belongs_to = (bool (*) (rsa_private_key_t*,rsa_public_key_t*))belongs_to;
- this->public.destroy = (void (*) (rsa_private_key_t*))destroy;
-
- /* private functions */
- this->rsadp = rsadp;
- this->rsasp1 = rsadp; /* same algorithm */
-
- this->keyid = chunk_empty;
-
- return this;
-}
-
-/*
- * See header
- */
-rsa_private_key_t *rsa_private_key_create(size_t key_size)
-{
- mpz_t p, q, n, e, d, exp1, exp2, coeff;
- mpz_t m, q1, t;
- private_rsa_private_key_t *this;
- size_t key_len = key_size / BITS_PER_BYTE;
- size_t prime_len = key_len / 2;
-
- /* Get values of primes p and q */
- if (compute_prime(this, prime_len, &p) != SUCCESS)
- {
- return NULL;
- }
- if (compute_prime(this, prime_len, &q) != SUCCESS)
- {
- mpz_clear(p);
- return NULL;
- }
-
- mpz_init(t);
- mpz_init(n);
- mpz_init(d);
- mpz_init(exp1);
- mpz_init(exp2);
- mpz_init(coeff);
-
- /* Swapping Primes so p is larger then q */
- if (mpz_cmp(p, q) < 0)
- {
- mpz_swap(p, q);
- }
-
- mpz_mul(n, p, q); /* n = p*q */
- mpz_init_set_ui(e, PUBLIC_EXPONENT); /* assign public exponent */
- mpz_init_set(m, p); /* m = p */
- mpz_sub_ui(m, m, 1); /* m = m -1 */
- mpz_init_set(q1, q); /* q1 = q */
- mpz_sub_ui(q1, q1, 1); /* q1 = q1 -1 */
- mpz_gcd(t, m, q1); /* t = gcd(p-1, q-1) */
- mpz_mul(m, m, q1); /* m = (p-1)*(q-1) */
- mpz_divexact(m, m, t); /* m = m / t */
- mpz_gcd(t, m, e); /* t = gcd(m, e) (greatest common divisor) */
-
- mpz_invert(d, e, m); /* e has an inverse mod m */
- if (mpz_cmp_ui(d, 0) < 0) /* make sure d is positive */
- {
- mpz_add(d, d, m);
- }
- mpz_sub_ui(t, p, 1); /* t = p-1 */
- mpz_mod(exp1, d, t); /* exp1 = d mod p-1 */
- mpz_sub_ui(t, q, 1); /* t = q-1 */
- mpz_mod(exp2, d, t); /* exp2 = d mod q-1 */
-
- mpz_invert(coeff, q, p); /* coeff = q^-1 mod p */
- if (mpz_cmp_ui(coeff, 0) < 0) /* make coeff d is positive */
- {
- mpz_add(coeff, coeff, p);
- }
-
- mpz_clear_randomized(q1);
- mpz_clear_randomized(m);
- mpz_clear_randomized(t);
-
- /* determine exact the modulus size in bits */
- key_size = mpz_sizeinbase(n, 2);
-
- /* create and fill in rsa_private_key_t object */
- this = rsa_private_key_create_empty();
- this->k = (key_size + 7) / BITS_PER_BYTE;
- this->keyid = rsa_public_key_id_create(n, e);
- *(this->p) = *p;
- *(this->q) = *q;
- *(this->n) = *n;
- *(this->e) = *e;
- *(this->d) = *d;
- *(this->exp1) = *exp1;
- *(this->exp2) = *exp2;
- *(this->coeff) = *coeff;
- DBG1("generated %d bit RSA key with keyid: %#B", key_size, &this->keyid);
-
- return &this->public;
-}
-
-/*
- * see header
- */
-rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t blob)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- private_rsa_private_key_t *this;
-
- this = rsa_private_key_create_empty();
-
- mpz_init(this->n);
- mpz_init(this->e);
- mpz_init(this->p);
- mpz_init(this->q);
- mpz_init(this->d);
- mpz_init(this->exp1);
- mpz_init(this->exp2);
- mpz_init(this->coeff);
-
- asn1_init(&ctx, blob, 0, FALSE, TRUE);
-
- while (objectID < PRIV_KEY_ROOF)
- {
- if (!extract_object(privkey_objects, &objectID, &object, &level, &ctx))
- {
- destroy(this);
- return FALSE;
- }
- switch (objectID)
- {
- case PRIV_KEY_VERSION:
- if (object.len > 0 && *object.ptr != 0)
- {
- destroy(this);
- return NULL;
- }
- break;
- case PRIV_KEY_MODULUS:
- mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_PUB_EXP:
- mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_PRIV_EXP:
- mpz_import(this->d, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_PRIME1:
- mpz_import(this->p, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_PRIME2:
- mpz_import(this->q, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_EXP1:
- mpz_import(this->exp1, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_EXP2:
- mpz_import(this->exp2, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PRIV_KEY_COEFF:
- mpz_import(this->coeff, object.len, 1, 1, 1, 0, object.ptr);
- break;
- }
- objectID++;
- }
-
- this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
- this->keyid = rsa_public_key_id_create(this->n, this->e);
-
- if (check(this) != SUCCESS)
- {
- destroy(this);
- return NULL;
- }
- else
- {
- return &this->public;
- }
-}
-
-/*
- * see header
- */
-rsa_private_key_t *rsa_private_key_create_from_file(char *filename, chunk_t *passphrase)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
- rsa_private_key_t *key = NULL;
-
- if (!pem_asn1_load_file(filename, passphrase, "private key", &chunk, &pgp))
- return NULL;
-
- key = rsa_private_key_create_from_chunk(chunk);
- chunk_free_randomized(&chunk);
- return key;
-}
diff --git a/src/libstrongswan/crypto/rsa/rsa_private_key.h b/src/libstrongswan/crypto/rsa/rsa_private_key.h
deleted file mode 100644
index 8013f03c2..000000000
--- a/src/libstrongswan/crypto/rsa/rsa_private_key.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
- * @file rsa_private_key.h
- *
- * @brief Interface of rsa_private_key_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: rsa_private_key.h 3423 2008-01-22 10:32:37Z andreas $
- */
-
-#ifndef RSA_PRIVATE_KEY_H_
-#define RSA_PRIVATE_KEY_H_
-
-typedef struct rsa_private_key_t rsa_private_key_t;
-
-#include <library.h>
-#include <crypto/rsa/rsa_public_key.h>
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief RSA private key with associated functions.
- *
- * Currently only supports signing using EMSA encoding.
- *
- * @b Constructors:
- * - rsa_private_key_create()
- * - rsa_private_key_create_from_chunk()
- * - rsa_private_key_create_from_file()
- *
- * @see rsa_public_key_t
- *
- * @ingroup rsa
- */
-struct rsa_private_key_t {
-
- /**
- * @brief Decrypt a data block based on EME-PKCS1 encoding.
- *
- *
- * @param this calling object
- * @param data encrypted input data
- * @param out decrypted output data
- * @return
- * - SUCCESS
- * - FAILED if padding is not correct
- */
- status_t (*pkcs1_decrypt) (rsa_private_key_t *this, chunk_t in, chunk_t *out);
-
- /**
- * @brief Build a signature over a chunk using EMSA-PKCS1 encoding.
- *
- * This signature creates a hash using the specified hash algorithm, concatenates
- * it with an ASN1-OID of the hash algorithm and runs the RSASP1 function
- * on it.
- *
- * @param this calling object
- * @param hash_algorithm hash algorithm to use for hashing
- * @param data data to sign
- * @param[out] signature allocated signature
- * @return
- * - SUCCESS
- * - INVALID_STATE, if key not set
- * - NOT_SUPPORTED, if hash algorithm not supported
- */
- status_t (*build_emsa_pkcs1_signature) (rsa_private_key_t *this, hash_algorithm_t hash_algorithm, chunk_t data, chunk_t *signature);
-
- /**
- * @brief Writes an RSA private key to a file in PKCS#1 format.
- *
- * @param this calling object
- * @param filename file to which the key should be written.
- * @param force if TRUE overwrite existing file
- * @return TRUE if successful - FALSE otherwise
- */
- bool (*pkcs1_write) (rsa_private_key_t *this, const char *filename, bool force);
-
- /**
- * @brief Create a rsa_public_key_t with the public part of the key.
- *
- * @param this calling object
- * @return public_key
- */
- rsa_public_key_t *(*get_public_key) (rsa_private_key_t *this);
-
- /**
- * @brief Check if a private key belongs to a public key.
- *
- * Compares the public part of the private key with the
- * public key, return TRUE if it equals.
- *
- * @param this private key
- * @param public public key
- * @return TRUE, if keys belong together
- */
- bool (*belongs_to) (rsa_private_key_t *this, rsa_public_key_t *public);
-
- /**
- * @brief Destroys the private key.
- *
- * @param this private key to destroy
- */
- void (*destroy) (rsa_private_key_t *this);
-};
-
-/**
- * @brief Generate a new RSA key with specified key length.
- *
- * @param key_size size of the key in bits
- * @return generated rsa_private_key_t.
- *
- * @ingroup rsa
- */
-rsa_private_key_t *rsa_private_key_create(size_t key_size);
-
-/**
- * @brief Load an RSA private key from a chunk.
- *
- * Load a key from a chunk, encoded as described in PKCS#1
- * (ASN1 DER encoded).
- *
- * @param chunk chunk containing the DER encoded key
- * @return loaded rsa_private_key_t, or NULL
- *
- * @ingroup rsa
- */
-rsa_private_key_t *rsa_private_key_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Load an RSA private key from a file.
- *
- * Load a key from a file, which is either in a unencrypted binary
- * format (DER), or in a (encrypted) PEM format. The supplied
- * passphrase is used to decrypt an ecrypted key.
- *
- * @param filename filename which holds the key
- * @param passphrase optional passphase for decryption, can be NULL
- * @return loaded rsa_private_key_t, or NULL
- *
- * @todo Implement PEM file loading
- * @todo Implement key decryption
- *
- * @ingroup rsa
- */
-rsa_private_key_t *rsa_private_key_create_from_file(char *filename, chunk_t *passphrase);
-
-#endif /*RSA_PRIVATE_KEY_H_*/
diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.c b/src/libstrongswan/crypto/rsa/rsa_public_key.c
deleted file mode 100644
index 10af0527e..000000000
--- a/src/libstrongswan/crypto/rsa/rsa_public_key.c
+++ /dev/null
@@ -1,516 +0,0 @@
-/**
- * @file rsa_public_key.c
- *
- * @brief Implementation of rsa_public_key_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: rsa_public_key.c 3428 2008-01-27 20:58:52Z andreas $
- */
-
-#include <gmp.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "rsa_public_key.h"
-
-#include <debug.h>
-#include <utils/randomizer.h>
-#include <crypto/hashers/hasher.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-
-/* ASN.1 definition of RSApublicKey */
-static const asn1Object_t pubkeyObjects[] = {
- { 0, "RSAPublicKey", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "modulus", ASN1_INTEGER, ASN1_BODY }, /* 1 */
- { 1, "publicExponent", ASN1_INTEGER, ASN1_BODY }, /* 2 */
-};
-
-#define PUB_KEY_RSA_PUBLIC_KEY 0
-#define PUB_KEY_MODULUS 1
-#define PUB_KEY_EXPONENT 2
-#define PUB_KEY_ROOF 3
-
-/* ASN.1 definition of digestInfo */
-static const asn1Object_t digestInfoObjects[] = {
- { 0, "digestInfo", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "digestAlgorithm", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 1, "digest", ASN1_OCTET_STRING, ASN1_BODY }, /* 2 */
-};
-
-#define DIGEST_INFO 0
-#define DIGEST_INFO_ALGORITHM 1
-#define DIGEST_INFO_DIGEST 2
-#define DIGEST_INFO_ROOF 3
-
-typedef struct private_rsa_public_key_t private_rsa_public_key_t;
-
-/**
- * Private data structure with signing context.
- */
-struct private_rsa_public_key_t {
- /**
- * Public interface for this signer.
- */
- rsa_public_key_t public;
-
- /**
- * Public modulus.
- */
- mpz_t n;
-
- /**
- * Public exponent.
- */
- mpz_t e;
-
- /**
- * Keysize in bytes.
- */
- size_t k;
-
- /**
- * Keyid formed as a SHA-1 hash of a publicKeyInfo object
- */
- chunk_t keyid;
-
- /**
- * @brief Implements the RSAEP algorithm specified in PKCS#1.
- *
- * @param this calling object
- * @param data data to process
- * @return processed data
- */
- chunk_t (*rsaep) (const private_rsa_public_key_t *this, chunk_t data);
-
- /**
- * @brief Implements the RSASVP1 algorithm specified in PKCS#1.
- *
- * @param this calling object
- * @param data data to process
- * @return processed data
- */
- chunk_t (*rsavp1) (const private_rsa_public_key_t *this, chunk_t data);
-};
-
-/**
- * Implementation of private_rsa_public_key_t.rsaep and private_rsa_public_key_t.rsavp1
- */
-static chunk_t rsaep(const private_rsa_public_key_t *this, chunk_t data)
-{
- mpz_t m, c;
- chunk_t encrypted;
-
- mpz_init(c);
- mpz_init(m);
-
- mpz_import(m, data.len, 1, 1, 1, 0, data.ptr);
-
- mpz_powm(c, m, this->e, this->n);
-
- encrypted.len = this->k;
- encrypted.ptr = mpz_export(NULL, NULL, 1, encrypted.len, 1, 0, c);
-
- mpz_clear(c);
- mpz_clear(m);
-
- return encrypted;
-}
-
-/**
- * Implementation of rsa_public_key_t.eme_pkcs1_encrypt.
- */
-static status_t pkcs1_encrypt(private_rsa_public_key_t *this,
- chunk_t in, chunk_t *out)
-{
- chunk_t em;
- u_char *pos;
- int padding = this->k - in.len - 3;
-
- if (padding < 8)
- {
- DBG1("rsa padding of %d bytes is too small", padding);
- return FAILED;
- }
- em.len = this->k;
- em.ptr = pos = malloc(em.len);
-
- /* add padding according to PKCS#1 7.2.1 1.+2. */
- *pos++ = 0x00;
- *pos++ = 0x02;
-
- /* pad with pseudo random bytes unequal to zero */
- {
- randomizer_t *randomizer = randomizer_create();
-
- /* pad with pseudo random bytes unequal to zero */
- while (padding--)
- {
- randomizer->get_pseudo_random_bytes(randomizer, 1, pos);
- while (!*pos)
- {
- randomizer->get_pseudo_random_bytes(randomizer, 1, pos);
- }
- pos++;
- }
- randomizer->destroy(randomizer);
- }
-
- /* append the padding terminator */
- *pos++ = 0x00;
-
- /* now add the data */
- memcpy(pos, in.ptr, in.len);
- *out = this->rsaep(this, em);
- free(em.ptr);
- return SUCCESS;
-}
-
-/**
- * Implementation of rsa_public_key.verify_emsa_pkcs1_signature.
- */
-static status_t verify_emsa_pkcs1_signature(const private_rsa_public_key_t *this,
- hash_algorithm_t algorithm,
- chunk_t data, chunk_t signature)
-{
- chunk_t em_ori, em;
- status_t res = FAILED;
-
- /* remove any preceding 0-bytes from signature */
- while (signature.len && *(signature.ptr) == 0x00)
- {
- signature.len -= 1;
- signature.ptr++;
- }
-
- if (signature.len > this->k)
- {
- return INVALID_ARG;
- }
-
- /* unpack signature */
- em_ori = em = this->rsavp1(this, signature);
-
- /* result should look like this:
- * EM = 0x00 || 0x01 || PS || 0x00 || T.
- * PS = 0xFF padding, with length to fill em
- * T = oid || hash
- */
-
- /* check magic bytes */
- if (*(em.ptr) != 0x00 || *(em.ptr+1) != 0x01)
- {
- DBG2("incorrect padding - probably wrong RSA key");
- goto end;
- }
- em.ptr += 2;
- em.len -= 2;
-
- /* find magic 0x00 */
- while (em.len > 0)
- {
- if (*em.ptr == 0x00)
- {
- /* found magic byte, stop */
- em.ptr++;
- em.len--;
- break;
- }
- else if (*em.ptr != 0xFF)
- {
- /* bad padding, decryption failed ?!*/
- goto end;
- }
- em.ptr++;
- em.len--;
- }
-
- if (em.len == 0)
- {
- /* no digestInfo found */
- goto end;
- }
-
- /* parse ASN.1-based digestInfo */
- {
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- hash_algorithm_t hash_algorithm = HASH_UNKNOWN;
-
- asn1_init(&ctx, em, 0, FALSE, FALSE);
-
- while (objectID < DIGEST_INFO_ROOF)
- {
- if (!extract_object(digestInfoObjects, &objectID, &object, &level, &ctx))
- {
- goto end;
- }
- switch (objectID)
- {
- case DIGEST_INFO:
- if (em.len > object.len)
- {
- DBG1("digestInfo field in signature is followed by %u surplus bytes",
- em.len - object.len);
- goto end;
- }
- break;
- case DIGEST_INFO_ALGORITHM:
- {
- int hash_oid = parse_algorithmIdentifier(object, level+1, NULL);
-
- hash_algorithm = hasher_algorithm_from_oid(hash_oid);
- if (hash_algorithm == HASH_UNKNOWN
- || (algorithm != HASH_UNKNOWN && hash_algorithm != algorithm))
- {
- DBG1("wrong hash algorithm used in signature");
- goto end;
- }
- }
- break;
- case DIGEST_INFO_DIGEST:
- {
- chunk_t hash;
- hasher_t *hasher = hasher_create(hash_algorithm);
-
- if (object.len != hasher->get_hash_size(hasher))
- {
- DBG1("hash size in signature is %u bytes instead of %u bytes",
- object.len, hasher->get_hash_size(hasher));
- hasher->destroy(hasher);
- goto end;
- }
-
- /* build our own hash */
- hasher->allocate_hash(hasher, data, &hash);
- hasher->destroy(hasher);
-
- /* compare the hashes */
- res = memeq(object.ptr, hash.ptr, hash.len) ? SUCCESS : FAILED;
- free(hash.ptr);
- }
- break;
- default:
- break;
- }
- objectID++;
- }
- }
-
-end:
- free(em_ori.ptr);
- return res;
-}
-
-
-/**
- * Implementation of rsa_public_key_t.get_modulus.
- */
-static mpz_t *get_modulus(const private_rsa_public_key_t *this)
-{
- return (mpz_t*)&this->n;
-}
-
-/**
- * Implementation of rsa_public_key_t.get_keysize.
- */
-static size_t get_keysize(const private_rsa_public_key_t *this)
-{
- return this->k;
-}
-
-/**
- * Build a DER-encoded publicKeyInfo object from an RSA public key.
- * Also used in rsa_private_key.c.
- */
-chunk_t rsa_public_key_info_to_asn1(const mpz_t n, const mpz_t e)
-{
- chunk_t publicKey = asn1_wrap(ASN1_SEQUENCE, "mm",
- asn1_integer_from_mpz(n),
- asn1_integer_from_mpz(e));
-
- return asn1_wrap(ASN1_SEQUENCE, "cm",
- asn1_algorithmIdentifier(OID_RSA_ENCRYPTION),
- asn1_bitstring("m", publicKey));
-}
-
-/**
- * Form the RSA keyid as a SHA-1 hash of a publicKeyInfo object
- * Also used in rsa_private_key.c.
- */
-chunk_t rsa_public_key_id_create(mpz_t n, mpz_t e)
-{
- chunk_t keyid;
- chunk_t publicKeyInfo = rsa_public_key_info_to_asn1(n, e);
- hasher_t *hasher = hasher_create(HASH_SHA1);
-
- hasher->allocate_hash(hasher, publicKeyInfo, &keyid);
- hasher->destroy(hasher);
- free(publicKeyInfo.ptr);
-
- return keyid;
-}
-
-/**
- * Implementation of rsa_public_key_t.get_publicKeyInfo.
- */
-static chunk_t get_publicKeyInfo(const private_rsa_public_key_t *this)
-{
- return rsa_public_key_info_to_asn1(this->n, this->e);
-}
-
-/**
- * Implementation of rsa_public_key_t.get_keyid.
- */
-static chunk_t get_keyid(const private_rsa_public_key_t *this)
-{
- return this->keyid;
-}
-
-/* forward declaration used by rsa_public_key_t.clone */
-private_rsa_public_key_t *rsa_public_key_create_empty(void);
-
-/**
- * Implementation of rsa_public_key_t.clone.
- */
-static rsa_public_key_t* _clone(const private_rsa_public_key_t *this)
-{
- private_rsa_public_key_t *clone = rsa_public_key_create_empty();
-
- mpz_init_set(clone->n, this->n);
- mpz_init_set(clone->e, this->e);
- clone->keyid = chunk_clone(this->keyid);
- clone->k = this->k;
-
- return &clone->public;
-}
-
-/**
- * Implementation of rsa_public_key_t.destroy.
- */
-static void destroy(private_rsa_public_key_t *this)
-{
- mpz_clear(this->n);
- mpz_clear(this->e);
- free(this->keyid.ptr);
- free(this);
-}
-
-/**
- * Generic private constructor
- */
-private_rsa_public_key_t *rsa_public_key_create_empty(void)
-{
- private_rsa_public_key_t *this = malloc_thing(private_rsa_public_key_t);
-
- /* public functions */
- this->public.pkcs1_encrypt = (status_t (*) (rsa_public_key_t*,chunk_t,chunk_t*))pkcs1_encrypt;
- this->public.verify_emsa_pkcs1_signature = (status_t (*) (const rsa_public_key_t*,hash_algorithm_t,chunk_t,chunk_t))verify_emsa_pkcs1_signature;
- this->public.get_modulus = (mpz_t *(*) (const rsa_public_key_t*))get_modulus;
- this->public.get_keysize = (size_t (*) (const rsa_public_key_t*))get_keysize;
- this->public.get_publicKeyInfo = (chunk_t (*) (const rsa_public_key_t*))get_publicKeyInfo;
- this->public.get_keyid = (chunk_t (*) (const rsa_public_key_t*))get_keyid;
- this->public.clone = (rsa_public_key_t* (*) (const rsa_public_key_t*))_clone;
- this->public.destroy = (void (*) (rsa_public_key_t*))destroy;
-
- /* private functions */
- this->rsaep = rsaep;
- this->rsavp1 = rsaep; /* same algorithm */
-
- return this;
-}
-
-/*
- * See header
- */
-rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e)
-{
- private_rsa_public_key_t *this = rsa_public_key_create_empty();
-
- mpz_init_set(this->n, n);
- mpz_init_set(this->e, e);
-
- this->k = (mpz_sizeinbase(n, 2) + 7) / BITS_PER_BYTE;
- this->keyid = rsa_public_key_id_create(n, e);
- return &this->public;
-}
-/*
- * See header
- */
-rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t blob)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- private_rsa_public_key_t *this = rsa_public_key_create_empty();
-
- mpz_init(this->n);
- mpz_init(this->e);
-
- asn1_init(&ctx, blob, 0, FALSE, FALSE);
-
- while (objectID < PUB_KEY_ROOF)
- {
- if (!extract_object(pubkeyObjects, &objectID, &object, &level, &ctx))
- {
- destroy(this);
- return FALSE;
- }
- switch (objectID)
- {
- case PUB_KEY_MODULUS:
- mpz_import(this->n, object.len, 1, 1, 1, 0, object.ptr);
- break;
- case PUB_KEY_EXPONENT:
- mpz_import(this->e, object.len, 1, 1, 1, 0, object.ptr);
- break;
- }
- objectID++;
- }
-
- this->k = (mpz_sizeinbase(this->n, 2) + 7) / BITS_PER_BYTE;
- this->keyid = rsa_public_key_id_create(this->n, this->e);
- return &this->public;
-}
-
-/*
- * See header
- */
-rsa_public_key_t *rsa_public_key_create_from_file(char *filename)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
- rsa_public_key_t *pubkey = NULL;
-
- if (!pem_asn1_load_file(filename, NULL, "public key", &chunk, &pgp))
- {
- return NULL;
- }
- pubkey = rsa_public_key_create_from_chunk(chunk);
- free(chunk.ptr);
- return pubkey;
-}
diff --git a/src/libstrongswan/crypto/rsa/rsa_public_key.h b/src/libstrongswan/crypto/rsa/rsa_public_key.h
deleted file mode 100644
index c0bd3e351..000000000
--- a/src/libstrongswan/crypto/rsa/rsa_public_key.h
+++ /dev/null
@@ -1,173 +0,0 @@
-/**
- * @file rsa_public_key.h
- *
- * @brief Interface of rsa_public_key_t.
- *
- */
-
-/*
- * Copyright (C) 2005 Jan Hutter
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2007-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: rsa_public_key.h 3423 2008-01-22 10:32:37Z andreas $
- */
-
-#ifndef RSA_PUBLIC_KEY_H_
-#define RSA_PUBLIC_KEY_H_
-
-typedef struct rsa_public_key_t rsa_public_key_t;
-
-#include <gmp.h>
-
-#include <library.h>
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief RSA public key with associated functions.
- *
- * Currently only supports signature verification using
- * the EMSA encoding (see PKCS1)
- *
- * @b Constructors:
- * - rsa_public_key_create()
- * - rsa_public_key_create_from_chunk()
- * - rsa_public_key_create_from_file()
- *
- * @ingroup rsa
- */
-struct rsa_public_key_t {
-
- /**
- * @brief Encrypt a data block using EME-PKCS1 encoding.
- *
- *
- * @param this calling object
- * @param data plaintext input data
- * @param out encrypted output data
- * @return
- * - SUCCESS
- * - FAILED if data block is too large
- */
- status_t (*pkcs1_encrypt) (rsa_public_key_t *this, chunk_t in, chunk_t *out);
-
- /**
- * @brief Verify an EMSA-PKCS1 encoded signature.
- *
- * Processes the supplied signature with the RSAVP1 function,
- * selects the hash algorithm form the resultign ASN1-OID and
- * verifies the hash against the supplied data.
- *
- * @param this rsa_public_key to use
- * @param data data to sign
- # @param algorithm hash algorithm the signature is based on
- * @param signature signature to verify
- * @return
- * - SUCCESS, if signature ok
- * - INVALID_STATE, if key not set
- * - NOT_SUPPORTED, if hash algorithm not supported
- * - INVALID_ARG, if signature is not a signature
- * - FAILED if signature invalid or unable to verify
- */
- status_t (*verify_emsa_pkcs1_signature) (const rsa_public_key_t *this,
- hash_algorithm_t algorithm,
- chunk_t data, chunk_t signature);
-
- /**
- * @brief Get the modulus of the key.
- *
- * @param this calling object
- * @return modulus (n) of the key
- */
- mpz_t *(*get_modulus) (const rsa_public_key_t *this);
-
- /**
- * @brief Get the size of the modulus in bytes.
- *
- * @param this calling object
- * @return size of the modulus (n) in bytes
- */
- size_t (*get_keysize) (const rsa_public_key_t *this);
-
- /**
- * @brief Get the DER encoded publicKeyInfo object.
- *
- * @param this calling object
- * @return DER encoded publicKeyInfo object
- */
- chunk_t (*get_publicKeyInfo) (const rsa_public_key_t *this);
-
- /**
- * @brief Get the keyid formed as the SHA-1 hash of a publicKeyInfo object.
- *
- * @param this calling object
- * @return keyid in the form of a SHA-1 hash
- */
- chunk_t (*get_keyid) (const rsa_public_key_t *this);
-
- /**
- * @brief Clone the public key.
- *
- * @param this public key to clone
- * @return clone of this
- */
- rsa_public_key_t *(*clone) (const rsa_public_key_t *this);
-
- /**
- * @brief Destroys the public key.
- *
- * @param this public key to destroy
- */
- void (*destroy) (rsa_public_key_t *this);
-};
-
-/**
- * @brief Create a RSA public key from modulus and public exponent.
- *
- * @param n modulus
- * @param e public exponent
- * @return created rsa_public_key_t
- *
- * @ingroup rsa
- */
-rsa_public_key_t *rsa_public_key_create(mpz_t n, mpz_t e);
-
-/**
- * @brief Load an RSA public key from a chunk.
- *
- * Load a key from a chunk, encoded in the more frequently
- * used publicKeyInfo object (ASN1 DER encoded).
- *
- * @param chunk chunk containing the DER encoded key
- * @return loaded rsa_public_key_t, or NULL
- *
- * @ingroup rsa
- */
-rsa_public_key_t *rsa_public_key_create_from_chunk(chunk_t chunk);
-
-/**
- * @brief Load an RSA public key from a file.
- *
- * Load a key from a file, which is either in binary
- * format (DER), or in PEM format.
- *
- * @param filename filename which holds the key
- * @return loaded rsa_public_key_t, or NULL
- *
- * @ingroup rsa
- */
-rsa_public_key_t *rsa_public_key_create_from_file(char *filename);
-
-#endif /*RSA_PUBLIC_KEY_H_*/
diff --git a/src/libstrongswan/crypto/signers/hmac_signer.c b/src/libstrongswan/crypto/signers/hmac_signer.c
deleted file mode 100644
index ad5b882a6..000000000
--- a/src/libstrongswan/crypto/signers/hmac_signer.c
+++ /dev/null
@@ -1,185 +0,0 @@
-/**
- * @file hmac_signer.c
- *
- * @brief Implementation of hmac_signer_t.
- *
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#include <string.h>
-
-#include "hmac_signer.h"
-
-#include <crypto/prfs/hmac_prf.h>
-
-typedef struct private_hmac_signer_t private_hmac_signer_t;
-
-/**
- * Private data structure with signing context.
- */
-struct private_hmac_signer_t {
- /**
- * Public interface of hmac_signer_t.
- */
- hmac_signer_t public;
-
- /**
- * Assigned hmac function.
- */
- prf_t *hmac_prf;
-
- /**
- * Block size (truncation of HMAC Hash)
- */
- size_t block_size;
-};
-
-/**
- * Implementation of signer_t.get_signature.
- */
-static void get_signature(private_hmac_signer_t *this, chunk_t data, u_int8_t *buffer)
-{
- if (buffer == NULL)
- { /* append mode */
- this->hmac_prf->get_bytes(this->hmac_prf, data, NULL);
- }
- else
- {
- u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
-
- this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
- memcpy(buffer, full_mac, this->block_size);
- }
-}
-
-/**
- * Implementation of signer_t.allocate_signature.
- */
-static void allocate_signature (private_hmac_signer_t *this, chunk_t data, chunk_t *chunk)
-{
- if (chunk == NULL)
- { /* append mode */
- this->hmac_prf->get_bytes(this->hmac_prf, data, NULL);
- }
- else
- {
- chunk_t signature;
- u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
-
- this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
-
- signature.ptr = malloc(this->block_size);
- signature.len = this->block_size;
-
- memcpy(signature.ptr, full_mac, this->block_size);
-
- *chunk = signature;
- }
-}
-
-/**
- * Implementation of signer_t.verify_signature.
- */
-static bool verify_signature(private_hmac_signer_t *this, chunk_t data, chunk_t signature)
-{
- u_int8_t full_mac[this->hmac_prf->get_block_size(this->hmac_prf)];
-
- this->hmac_prf->get_bytes(this->hmac_prf, data, full_mac);
-
- if (signature.len != this->block_size)
- {
- return FALSE;
- }
-
- /* compare mac aka signature :-) */
- if (memcmp(signature.ptr, full_mac, this->block_size) == 0)
- {
- return TRUE;
- }
- else
- {
- return FALSE;
- }
-}
-
-/**
- * Implementation of signer_t.get_key_size.
- */
-static size_t get_key_size(private_hmac_signer_t *this)
-{
- /* for HMAC signer, IKEv2 uses block size as key size */
- return this->hmac_prf->get_block_size(this->hmac_prf);
-}
-
-/**
- * Implementation of signer_t.get_block_size.
- */
-static size_t get_block_size(private_hmac_signer_t *this)
-{
- return this->block_size;
-}
-
-/**
- * Implementation of signer_t.set_key.
- */
-static void set_key(private_hmac_signer_t *this, chunk_t key)
-{
- this->hmac_prf->set_key(this->hmac_prf, key);
-}
-
-/**
- * Implementation of signer_t.destroy.
- */
-static status_t destroy(private_hmac_signer_t *this)
-{
- this->hmac_prf->destroy(this->hmac_prf);
- free(this);
- return SUCCESS;
-}
-
-/*
- * Described in header
- */
-hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm, size_t block_size)
-{
- size_t hmac_block_size;
- private_hmac_signer_t *this = malloc_thing(private_hmac_signer_t);
-
- this->hmac_prf = (prf_t *) hmac_prf_create(hash_algoritm);
- if (this->hmac_prf == NULL)
- {
- /* algorithm not supported */
- free(this);
- return NULL;
- }
-
- /* prevent invalid truncation */
- hmac_block_size = this->hmac_prf->get_block_size(this->hmac_prf);
- this->block_size = min(block_size, hmac_block_size);
-
- /* interface functions */
- this->public.signer_interface.get_signature = (void (*) (signer_t*, chunk_t, u_int8_t*))get_signature;
- this->public.signer_interface.allocate_signature = (void (*) (signer_t*, chunk_t, chunk_t*))allocate_signature;
- this->public.signer_interface.verify_signature = (bool (*) (signer_t*, chunk_t, chunk_t))verify_signature;
- this->public.signer_interface.get_key_size = (size_t (*) (signer_t*))get_key_size;
- this->public.signer_interface.get_block_size = (size_t (*) (signer_t*))get_block_size;
- this->public.signer_interface.set_key = (void (*) (signer_t*,chunk_t))set_key;
- this->public.signer_interface.destroy = (void (*) (signer_t*))destroy;
-
- return &(this->public);
-}
diff --git a/src/libstrongswan/crypto/signers/hmac_signer.h b/src/libstrongswan/crypto/signers/hmac_signer.h
deleted file mode 100644
index 2449069bd..000000000
--- a/src/libstrongswan/crypto/signers/hmac_signer.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file hmac_signer.h
- *
- * @brief Interface of hmac_signer_t.
- *
- */
-
-/*
- * Copyright (C) 2005-2006 Martin Willi
- * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- */
-
-#ifndef HMAC_SIGNER_H_
-#define HMAC_SIGNER_H_
-
-typedef struct hmac_signer_t hmac_signer_t;
-
-#include <crypto/signers/signer.h>
-#include <crypto/hashers/hasher.h>
-
-/**
- * @brief Implementation of signer_t interface using HMAC.
- *
- * HMAC uses a standard hash function implemented in a hasher_t to build
- * a MAC.
- *
- * @ingroup signers
- */
-struct hmac_signer_t {
-
- /**
- * generic signer_t interface for this signer
- */
- signer_t signer_interface;
-};
-
-/**
- * @brief Creates a new hmac_signer_t.
- *
- * HMAC signatures are often truncated to shorten them to a more usable, but
- * still secure enough length.
- * Block size must be equal or smaller then the hash algorithms
- * hash.
- *
- * @param hash_algoritm Hash algorithm to use with signer
- * @param block_size Size of resulting signature (truncated to block_size)
- * @return
- * - hmac_signer_t
- * - NULL if hash algorithm not supported
- *
- * @ingroup signers
- */
-hmac_signer_t *hmac_signer_create(hash_algorithm_t hash_algoritm,
- size_t block_size);
-
-
-#endif /*HMAC_SIGNER_H_*/
diff --git a/src/libstrongswan/crypto/signers/signer.c b/src/libstrongswan/crypto/signers/signer.c
index 747bc5efa..8412ff62e 100644
--- a/src/libstrongswan/crypto/signers/signer.c
+++ b/src/libstrongswan/crypto/signers/signer.c
@@ -1,10 +1,3 @@
-/**
- * @file signer.c
- *
- * @brief Implementation of generic signer_t constructor.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,12 +12,12 @@
* 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.
+ *
+ * $Id: signer.c 3589 2008-03-13 14:14:44Z martin $
*/
#include "signer.h"
-#include <crypto/signers/hmac_signer.h>
-
ENUM_BEGIN(integrity_algorithm_names, AUTH_UNDEFINED, AUTH_HMAC_SHA1_128,
"UNDEFINED",
"AUTH_HMAC_SHA1_128");
@@ -40,26 +33,3 @@ ENUM_NEXT(integrity_algorithm_names, AUTH_HMAC_SHA2_256_128, AUTH_HMAC_SHA2_512_
"AUTH_HMAC_SHA2_512_256");
ENUM_END(integrity_algorithm_names, AUTH_HMAC_SHA2_512_256);
-/*
- * Described in header.
- */
-signer_t *signer_create(integrity_algorithm_t integrity_algorithm)
-{
- switch(integrity_algorithm)
- {
- case AUTH_HMAC_SHA1_96:
- return (signer_t *)hmac_signer_create(HASH_SHA1, 12);
- case AUTH_HMAC_SHA1_128:
- return (signer_t *)hmac_signer_create(HASH_SHA1, 16);
- case AUTH_HMAC_MD5_96:
- return (signer_t *)hmac_signer_create(HASH_MD5, 12);
- case AUTH_HMAC_SHA2_256_128:
- return (signer_t *)hmac_signer_create(HASH_SHA256, 16);
- case AUTH_HMAC_SHA2_384_192:
- return (signer_t *)hmac_signer_create(HASH_SHA384, 24);
- case AUTH_HMAC_SHA2_512_256:
- return (signer_t *)hmac_signer_create(HASH_SHA512, 32);
- default:
- return NULL;
- }
-}
diff --git a/src/libstrongswan/crypto/signers/signer.h b/src/libstrongswan/crypto/signers/signer.h
index 4218e4146..f67c38f07 100644
--- a/src/libstrongswan/crypto/signers/signer.h
+++ b/src/libstrongswan/crypto/signers/signer.h
@@ -1,10 +1,3 @@
-/**
- * @file signer.h
- *
- * @brief Interface for signer_t.
- *
- */
-
/*
* Copyright (C) 2005-2006 Martin Willi
* Copyright (C) 2005 Jan Hutter
@@ -19,6 +12,13 @@
* 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.
+ *
+ * $Id: signer.h 3589 2008-03-13 14:14:44Z martin $
+ */
+
+/**
+ * @defgroup signer signer
+ * @{ @ingroup crypto
*/
#ifndef SIGNER_H_
@@ -30,11 +30,9 @@ typedef struct signer_t signer_t;
#include <library.h>
/**
- * @brief Integrity algorithm, as in IKEv2 RFC 3.3.2.
+ * Integrity algorithm, as in IKEv2 RFC 3.3.2.
*
* Algorithms not specified in IKEv2 are allocated in private use space.
- *
- * @ingroup signers
*/
enum integrity_algorithm_t {
AUTH_UNDEFINED = 1024,
@@ -61,93 +59,65 @@ enum integrity_algorithm_t {
extern enum_name_t *integrity_algorithm_names;
/**
- * @brief Generig interface for a symmetric signature algorithm.
- *
- * @b Constructors:
- * - signer_create()
- * - hmac_signer_create()
- *
- * @todo Implement more integrity algorithms
- *
- * @ingroup signers
+ * Generig interface for a symmetric signature algorithm.
*/
struct signer_t {
/**
- * @brief Generate a signature.
+ * Generate a signature.
*
* If buffer is NULL, data is processed and prepended to a next call until
* buffer is a valid pointer.
*
- * @param this calling object
- * @param data a chunk containing the data to sign
- * @param[out] buffer pointer where the signature will be written
+ * @param data a chunk containing the data to sign
+ * @param buffer pointer where the signature will be written
*/
void (*get_signature) (signer_t *this, chunk_t data, u_int8_t *buffer);
/**
- * @brief Generate a signature and allocate space for it.
+ * Generate a signature and allocate space for it.
*
* If chunk is NULL, data is processed and prepended to a next call until
* chunk is a valid chunk pointer.
*
- * @param this calling object
- * @param data a chunk containing the data to sign
- * @param[out] chunk chunk which will hold the allocated signature
+ * @param data a chunk containing the data to sign
+ * @param chunk chunk which will hold the allocated signature
*/
void (*allocate_signature) (signer_t *this, chunk_t data, chunk_t *chunk);
/**
- * @brief Verify a signature.
+ * Verify a signature.
*
- * @param this calling object
- * @param data a chunk containing the data to verify
- * @param signature a chunk containing the signature
- * @return TRUE, if signature is valid, FALSE otherwise
+ * @param data a chunk containing the data to verify
+ * @param signature a chunk containing the signature
+ * @return TRUE, if signature is valid, FALSE otherwise
*/
bool (*verify_signature) (signer_t *this, chunk_t data, chunk_t signature);
/**
- * @brief Get the block size of this signature algorithm.
+ * Get the block size of this signature algorithm.
*
- * @param this calling object
- * @return block size in bytes
+ * @return block size in bytes
*/
size_t (*get_block_size) (signer_t *this);
/**
- * @brief Get the key size of the signature algorithm.
+ * Get the key size of the signature algorithm.
*
- * @param this calling object
- * @return key size in bytes
+ * @return key size in bytes
*/
size_t (*get_key_size) (signer_t *this);
/**
- * @brief Set the key for this object.
+ * Set the key for this object.
*
- * @param this calling object
- * @param key key to set
+ * @param key key to set
*/
void (*set_key) (signer_t *this, chunk_t key);
/**
- * @brief Destroys a signer_t object.
- *
- * @param this calling object
+ * Destroys a signer_t object.
*/
void (*destroy) (signer_t *this);
};
-/**
- * @brief Creates a new signer_t object.
- *
- * @param integrity_algorithm Algorithm to use for signing and verifying.
- * @return
- * - signer_t object
- * - NULL if signer not supported
- *
- * @ingroup signers
- */
-signer_t *signer_create(integrity_algorithm_t integrity_algorithm);
-
-#endif /*SIGNER_H_*/
+#endif /*SIGNER_H_ @} */
diff --git a/src/libstrongswan/crypto/x509.c b/src/libstrongswan/crypto/x509.c
deleted file mode 100755
index eadf11327..000000000
--- a/src/libstrongswan/crypto/x509.c
+++ /dev/null
@@ -1,1562 +0,0 @@
-/**
- * @file x509.c
- *
- * @brief Implementation of x509_t.
- *
- */
-
-/*
- * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
- * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
- * Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2006 Martin Willi
- * Copyright (C) 2000-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: x509.c 3423 2008-01-22 10:32:37Z andreas $
- */
-
-#include <gmp.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "x509.h"
-#include "hashers/hasher.h"
-#include <library.h>
-#include <debug.h>
-#include <asn1/oid.h>
-#include <asn1/asn1.h>
-#include <asn1/pem.h>
-#include <utils/linked_list.h>
-#include <utils/identification.h>
-
-#define CERT_WARNING_INTERVAL 30 /* days */
-
-/**
- * Different kinds of generalNames
- */
-typedef enum generalNames_t generalNames_t;
-
-enum generalNames_t {
- GN_OTHER_NAME = 0,
- GN_RFC822_NAME = 1,
- GN_DNS_NAME = 2,
- GN_X400_ADDRESS = 3,
- GN_DIRECTORY_NAME = 4,
- GN_EDI_PARTY_NAME = 5,
- GN_URI = 6,
- GN_IP_ADDRESS = 7,
- GN_REGISTERED_ID = 8,
-};
-
-typedef struct private_x509_t private_x509_t;
-
-/**
- * Private data of a x509_t object.
- */
-struct private_x509_t {
- /**
- * Public interface for this certificate.
- */
- x509_t public;
-
- /**
- * Time when certificate was installed
- */
- time_t installed;
-
- /**
- * Time until certificate can be trusted
- */
- time_t until;
-
- /**
- * Certificate status
- */
- cert_status_t status;
-
- /**
- * Authority flags
- */
- u_int authority_flags;
-
- /**
- * X.509 Certificate in DER format
- */
- chunk_t certificate;
-
- /**
- * X.509 certificate body over which signature is computed
- */
- chunk_t tbsCertificate;
-
- /**
- * Version of the X.509 certificate
- */
- u_int version;
-
- /**
- * Serial number of the X.509 certificate
- */
- chunk_t serialNumber;
-
- /**
- * Signature algorithm
- */
- int signatureAlgorithm;
-
- /**
- * ID representing the certificate issuer
- */
- identification_t *issuer;
-
- /**
- * link to the info recored of the certificate issuer
- */
- ca_info_t *ca_info;
-
- /**
- * Start time of certificate validity
- */
- time_t notBefore;
-
- /**
- * End time of certificate validity
- */
- time_t notAfter;
-
- /**
- * ID representing the certificate subject
- */
- identification_t *subject;
-
- /**
- * List of identification_t's representing subjectAltNames
- */
- linked_list_t *subjectAltNames;
-
- /**
- * List of identification_t's representing crlDistributionPoints
- */
- linked_list_t *crlDistributionPoints;
-
- /**
- * List of identification_t's representing ocspAccessLocations
- */
- linked_list_t *ocspAccessLocations;
-
- /**
- * Subject public key
- */
- chunk_t subjectPublicKey;
-
- /**
- * Subject RSA public key, if subjectPublicKeyAlgorithm == RSA
- */
- rsa_public_key_t *public_key;
-
- /**
- * Subject Key Identifier
- */
- chunk_t subjectKeyID;
-
- /**
- * Authority Key Identifier
- */
- chunk_t authKeyID;
-
- /**
- * Authority Key Serial Number
- */
- chunk_t authKeySerialNumber;
-
- /**
- * Indicates if the certificate is self-signed
- */
- bool isSelfSigned;
-
- /**
- * CA basic constraints flag
- */
- bool isCA;
-
- /**
- * OCSPSigner extended key usage flag
- */
- bool isOcspSigner;
-
- /**
- * Signature
- */
- chunk_t signature;
-
-};
-
-/**
- * ASN.1 definition of generalName
- */
-static const asn1Object_t generalNameObjects[] = {
- { 0, "otherName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_BODY }, /* 0 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 1 */
- { 0, "rfc822Name", ASN1_CONTEXT_S_1, ASN1_OPT|ASN1_BODY }, /* 2 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 3 */
- { 0, "dnsName", ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 4 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 5 */
- { 0, "x400Address", ASN1_CONTEXT_S_3, ASN1_OPT|ASN1_BODY }, /* 6 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 7 */
- { 0, "directoryName", ASN1_CONTEXT_C_4, ASN1_OPT|ASN1_BODY }, /* 8 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 9 */
- { 0, "ediPartyName", ASN1_CONTEXT_C_5, ASN1_OPT|ASN1_BODY }, /* 10 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 11 */
- { 0, "URI", ASN1_CONTEXT_S_6, ASN1_OPT|ASN1_BODY }, /* 12 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 13 */
- { 0, "ipAddress", ASN1_CONTEXT_S_7, ASN1_OPT|ASN1_BODY }, /* 14 */
- { 0, "end choice", ASN1_EOC, ASN1_END }, /* 15 */
- { 0, "registeredID", ASN1_CONTEXT_S_8, ASN1_OPT|ASN1_BODY }, /* 16 */
- { 0, "end choice", ASN1_EOC, ASN1_END } /* 17 */
-};
-#define GN_OBJ_OTHER_NAME 0
-#define GN_OBJ_RFC822_NAME 2
-#define GN_OBJ_DNS_NAME 4
-#define GN_OBJ_X400_ADDRESS 6
-#define GN_OBJ_DIRECTORY_NAME 8
-#define GN_OBJ_EDI_PARTY_NAME 10
-#define GN_OBJ_URI 12
-#define GN_OBJ_IP_ADDRESS 14
-#define GN_OBJ_REGISTERED_ID 16
-#define GN_OBJ_ROOF 18
-
-/**
- * ASN.1 definition of otherName
- */
-static const asn1Object_t otherNameObjects[] = {
- {0, "type-id", ASN1_OID, ASN1_BODY }, /* 0 */
- {0, "value", ASN1_CONTEXT_C_0, ASN1_BODY } /* 1 */
-};
-#define ON_OBJ_ID_TYPE 0
-#define ON_OBJ_VALUE 1
-#define ON_OBJ_ROOF 2
-/**
- * ASN.1 definition of a basicConstraints extension
- */
-static const asn1Object_t basicConstraintsObjects[] = {
- { 0, "basicConstraints", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "CA", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 1 */
- { 1, "pathLenConstraint", ASN1_INTEGER, ASN1_OPT|ASN1_BODY }, /* 2 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 3 */
-};
-#define BASIC_CONSTRAINTS_CA 1
-#define BASIC_CONSTRAINTS_ROOF 4
-
-/**
- * ASN.1 definition of a keyIdentifier
- */
-static const asn1Object_t keyIdentifierObjects[] = {
- { 0, "keyIdentifier", ASN1_OCTET_STRING, ASN1_BODY } /* 0 */
-};
-
-/**
- * ASN.1 definition of a authorityKeyIdentifier extension
- */
-static const asn1Object_t authorityKeyIdentifierObjects[] = {
- { 0, "authorityKeyIdentifier", ASN1_SEQUENCE, ASN1_NONE }, /* 0 */
- { 1, "keyIdentifier", ASN1_CONTEXT_S_0, ASN1_OPT|ASN1_OBJ }, /* 1 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 2 */
- { 1, "authorityCertIssuer", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_OBJ }, /* 3 */
- { 1, "end opt", ASN1_EOC, ASN1_END }, /* 4 */
- { 1, "authorityCertSerialNumber",ASN1_CONTEXT_S_2, ASN1_OPT|ASN1_BODY }, /* 5 */
- { 1, "end opt", ASN1_EOC, ASN1_END } /* 6 */
-};
-#define AUTH_KEY_ID_KEY_ID 1
-#define AUTH_KEY_ID_CERT_ISSUER 3
-#define AUTH_KEY_ID_CERT_SERIAL 5
-#define AUTH_KEY_ID_ROOF 7
-
-/**
- * ASN.1 definition of a authorityInfoAccess extension
- */
-static const asn1Object_t authorityInfoAccessObjects[] = {
- { 0, "authorityInfoAccess", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "accessDescription", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "accessMethod", ASN1_OID, ASN1_BODY }, /* 2 */
- { 2, "accessLocation", ASN1_EOC, ASN1_RAW }, /* 3 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 4 */
-};
-#define AUTH_INFO_ACCESS_METHOD 2
-#define AUTH_INFO_ACCESS_LOCATION 3
-#define AUTH_INFO_ACCESS_ROOF 5
-
-/**
- * ASN.1 definition of a extendedKeyUsage extension
- */
-static const asn1Object_t extendedKeyUsageObjects[] = {
- { 0, "extendedKeyUsage", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "keyPurposeID", ASN1_OID, ASN1_BODY }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 2 */
-};
-
-#define EXT_KEY_USAGE_PURPOSE_ID 1
-#define EXT_KEY_USAGE_ROOF 3
-
-/**
- * ASN.1 definition of generalNames
- */
-static const asn1Object_t generalNamesObjects[] = {
- { 0, "generalNames", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "generalName", ASN1_EOC, ASN1_RAW }, /* 1 */
- { 0, "end loop", ASN1_EOC, ASN1_END } /* 2 */
-};
-#define GENERAL_NAMES_GN 1
-#define GENERAL_NAMES_ROOF 3
-
-
-/**
- * ASN.1 definition of crlDistributionPoints
- */
-static const asn1Object_t crlDistributionPointsObjects[] = {
- { 0, "crlDistributionPoints", ASN1_SEQUENCE, ASN1_LOOP }, /* 0 */
- { 1, "DistributionPoint", ASN1_SEQUENCE, ASN1_NONE }, /* 1 */
- { 2, "distributionPoint", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_LOOP }, /* 2 */
- { 3, "fullName", ASN1_CONTEXT_C_0, ASN1_OPT|ASN1_OBJ }, /* 3 */
- { 3, "end choice", ASN1_EOC, ASN1_END }, /* 4 */
- { 3, "nameRelToCRLIssuer",ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 5 */
- { 3, "end choice", ASN1_EOC, ASN1_END }, /* 6 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 7 */
- { 2, "reasons", ASN1_CONTEXT_C_1, ASN1_OPT|ASN1_BODY }, /* 8 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 9 */
- { 2, "crlIssuer", ASN1_CONTEXT_C_2, ASN1_OPT|ASN1_BODY }, /* 10 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 11 */
- { 0, "end loop", ASN1_EOC, ASN1_END }, /* 12 */
-};
-#define CRL_DIST_POINTS_FULLNAME 3
-#define CRL_DIST_POINTS_ROOF 13
-
-/**
- * ASN.1 definition of an X.509v3 x509
- */
-static const asn1Object_t certObjects[] = {
- { 0, "x509", ASN1_SEQUENCE, ASN1_OBJ }, /* 0 */
- { 1, "tbsCertificate", ASN1_SEQUENCE, ASN1_OBJ }, /* 1 */
- { 2, "DEFAULT v1", ASN1_CONTEXT_C_0, ASN1_DEF }, /* 2 */
- { 3, "version", ASN1_INTEGER, ASN1_BODY }, /* 3 */
- { 2, "serialNumber", ASN1_INTEGER, ASN1_BODY }, /* 4 */
- { 2, "signature", ASN1_EOC, ASN1_RAW }, /* 5 */
- { 2, "issuer", ASN1_SEQUENCE, ASN1_OBJ }, /* 6 */
- { 2, "validity", ASN1_SEQUENCE, ASN1_NONE }, /* 7 */
- { 3, "notBefore", ASN1_EOC, ASN1_RAW }, /* 8 */
- { 3, "notAfter", ASN1_EOC, ASN1_RAW }, /* 9 */
- { 2, "subject", ASN1_SEQUENCE, ASN1_OBJ }, /* 10 */
- { 2, "subjectPublicKeyInfo",ASN1_SEQUENCE, ASN1_NONE }, /* 11 */
- { 3, "algorithm", ASN1_EOC, ASN1_RAW }, /* 12 */
- { 3, "subjectPublicKey", ASN1_BIT_STRING, ASN1_NONE }, /* 13 */
- { 4, "RSAPublicKey", ASN1_SEQUENCE, ASN1_RAW }, /* 14 */
- { 2, "issuerUniqueID", ASN1_CONTEXT_C_1, ASN1_OPT }, /* 15 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 16 */
- { 2, "subjectUniqueID", ASN1_CONTEXT_C_2, ASN1_OPT }, /* 17 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 18 */
- { 2, "optional extensions", ASN1_CONTEXT_C_3, ASN1_OPT }, /* 19 */
- { 3, "extensions", ASN1_SEQUENCE, ASN1_LOOP }, /* 20 */
- { 4, "extension", ASN1_SEQUENCE, ASN1_NONE }, /* 21 */
- { 5, "extnID", ASN1_OID, ASN1_BODY }, /* 22 */
- { 5, "critical", ASN1_BOOLEAN, ASN1_DEF|ASN1_BODY }, /* 23 */
- { 5, "extnValue", ASN1_OCTET_STRING, ASN1_BODY }, /* 24 */
- { 3, "end loop", ASN1_EOC, ASN1_END }, /* 25 */
- { 2, "end opt", ASN1_EOC, ASN1_END }, /* 26 */
- { 1, "signatureAlgorithm", ASN1_EOC, ASN1_RAW }, /* 27 */
- { 1, "signatureValue", ASN1_BIT_STRING, ASN1_BODY } /* 28 */
-};
-#define X509_OBJ_CERTIFICATE 0
-#define X509_OBJ_TBS_CERTIFICATE 1
-#define X509_OBJ_VERSION 3
-#define X509_OBJ_SERIAL_NUMBER 4
-#define X509_OBJ_SIG_ALG 5
-#define X509_OBJ_ISSUER 6
-#define X509_OBJ_NOT_BEFORE 8
-#define X509_OBJ_NOT_AFTER 9
-#define X509_OBJ_SUBJECT 10
-#define X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM 12
-#define X509_OBJ_SUBJECT_PUBLIC_KEY 13
-#define X509_OBJ_RSA_PUBLIC_KEY 14
-#define X509_OBJ_EXTN_ID 22
-#define X509_OBJ_CRITICAL 23
-#define X509_OBJ_EXTN_VALUE 24
-#define X509_OBJ_ALGORITHM 27
-#define X509_OBJ_SIGNATURE 28
-#define X509_OBJ_ROOF 29
-
-
-static u_char ASN1_subjectAltName_oid_str[] = {
- 0x06, 0x03, 0x55, 0x1D, 0x11
-};
-
-static const chunk_t ASN1_subjectAltName_oid = chunk_from_buf(ASN1_subjectAltName_oid_str);
-
-
-/**
- * compare two X.509 x509s by comparing their signatures
- */
-static bool equals(const private_x509_t *this, const private_x509_t *other)
-{
- return chunk_equals(this->signature, other->signature);
-}
-
-/**
- * extracts the basicConstraints extension
- */
-static bool parse_basicConstraints(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- bool isCA = FALSE;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < BASIC_CONSTRAINTS_ROOF) {
-
- if (!extract_object(basicConstraintsObjects, &objectID, &object,&level, &ctx))
- {
- break;
- }
- if (objectID == BASIC_CONSTRAINTS_CA)
- {
- isCA = object.len && *object.ptr;
- DBG2(" %s", isCA ? "TRUE" : "FALSE");
- }
- objectID++;
- }
- return isCA;
-}
-
-/**
- * extracts an otherName
- */
-static bool parse_otherName(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < ON_OBJ_ROOF)
- {
- if (!extract_object(otherNameObjects, &objectID, &object, &level, &ctx))
- return FALSE;
-
- switch (objectID)
- {
- case ON_OBJ_ID_TYPE:
- oid = known_oid(object);
- break;
- case ON_OBJ_VALUE:
- if (oid == OID_XMPP_ADDR)
- {
- if (!parse_asn1_simple_object(&object, ASN1_UTF8STRING, level + 1, "xmppAddr"))
- return FALSE;
- }
- break;
- default:
- break;
- }
- objectID++;
- }
- return TRUE;
-}
-
-/**
- * extracts a generalName
- */
-static identification_t *parse_generalName(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- int objectID = 0;
- u_int level;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < GN_OBJ_ROOF)
- {
- id_type_t id_type = ID_ANY;
-
- if (!extract_object(generalNameObjects, &objectID, &object, &level, &ctx))
- return NULL;
-
- switch (objectID)
- {
- case GN_OBJ_RFC822_NAME:
- id_type = ID_RFC822_ADDR;
- break;
- case GN_OBJ_DNS_NAME:
- id_type = ID_FQDN;
- break;
- case GN_OBJ_URI:
- id_type = ID_DER_ASN1_GN_URI;
- break;
- case GN_OBJ_DIRECTORY_NAME:
- id_type = ID_DER_ASN1_DN;
- break;
- case GN_OBJ_IP_ADDRESS:
- id_type = (object.len == 4)? ID_IPV4_ADDR : ID_IPV6_ADDR;
- break;
- case GN_OBJ_OTHER_NAME:
- if (!parse_otherName(object, level + 1))
- return NULL;
- break;
- case GN_OBJ_X400_ADDRESS:
- case GN_OBJ_EDI_PARTY_NAME:
- case GN_OBJ_REGISTERED_ID:
- break;
- default:
- break;
- }
-
- if (id_type != ID_ANY)
- {
- identification_t *gn = identification_create_from_encoding(id_type, object);
- DBG2(" '%D'", gn);
- return gn;
- }
- objectID++;
- }
- return NULL;
-}
-
-
-/*
- * Defined in header.
- */
-void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, implicit, FALSE);
-
- while (objectID < GENERAL_NAMES_ROOF)
- {
- if (!extract_object(generalNamesObjects, &objectID, &object, &level, &ctx))
- return;
-
- if (objectID == GENERAL_NAMES_GN)
- {
- identification_t *gn = parse_generalName(object, level+1);
-
- if (gn != NULL)
- list->insert_last(list, (void *)gn);
- }
- objectID++;
- }
- return;
-}
-
-/**
- * extracts a keyIdentifier
- */
-static chunk_t parse_keyIdentifier(chunk_t blob, int level0, bool implicit)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, implicit, FALSE);
-
- extract_object(keyIdentifierObjects, &objectID, &object, &level, &ctx);
- return object;
-}
-
-/*
- * Defined in header.
- */
-void x509_parse_authorityKeyIdentifier(chunk_t blob, int level0 , chunk_t *authKeyID, chunk_t *authKeySerialNumber)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- *authKeyID = chunk_empty;
- *authKeySerialNumber = chunk_empty;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
-
- while (objectID < AUTH_KEY_ID_ROOF)
- {
- if (!extract_object(authorityKeyIdentifierObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
- switch (objectID)
- {
- case AUTH_KEY_ID_KEY_ID:
- *authKeyID = parse_keyIdentifier(object, level+1, TRUE);
- break;
- case AUTH_KEY_ID_CERT_ISSUER:
- {
- /* TODO: parse_generalNames(object, level+1, TRUE); */
- break;
- }
- case AUTH_KEY_ID_CERT_SERIAL:
- *authKeySerialNumber = object;
- break;
- default:
- break;
- }
- objectID++;
- }
-}
-
-/**
- * extracts an authorityInfoAcess location
- */
-static void parse_authorityInfoAccess(chunk_t blob, int level0, linked_list_t *list)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int accessMethod = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
- while (objectID < AUTH_INFO_ACCESS_ROOF)
- {
- if (!extract_object(authorityInfoAccessObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
- switch (objectID)
- {
- case AUTH_INFO_ACCESS_METHOD:
- accessMethod = known_oid(object);
- break;
- case AUTH_INFO_ACCESS_LOCATION:
- {
- switch (accessMethod)
- {
- case OID_OCSP:
- case OID_CA_ISSUERS:
- {
- identification_t *accessLocation;
-
- accessLocation = parse_generalName(object, level+1);
- if (accessLocation == NULL)
- {
- /* parsing went wrong - abort */
- return;
- }
- DBG2(" '%D'", accessLocation);
- if (accessMethod == OID_OCSP)
- {
- list->insert_last(list, (void *)accessLocation);
- }
- else
- {
- /* caIsssuer accessLocation is not used yet */
- accessLocation->destroy(accessLocation);
- }
- }
- break;
- default:
- /* unkown accessMethod, ignoring */
- break;
- }
- break;
- }
- default:
- break;
- }
- objectID++;
- }
-}
-
-/**
- * extracts extendedKeyUsage OIDs
- */
-static bool parse_extendedKeyUsage(chunk_t blob, int level0)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
- while (objectID < EXT_KEY_USAGE_ROOF)
- {
- if (!extract_object(extendedKeyUsageObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
- if (objectID == EXT_KEY_USAGE_PURPOSE_ID &&
- known_oid(object) == OID_OCSP_SIGNING)
- {
- return TRUE;
- }
- objectID++;
- }
- return FALSE;
-}
-
-/**
- * extracts one or several crlDistributionPoints and puts them into
- * a chained list
- */
-static void parse_crlDistributionPoints(chunk_t blob, int level0, linked_list_t *list)
-{
- asn1_ctx_t ctx;
- chunk_t object;
- u_int level;
- int objectID = 0;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
- while (objectID < CRL_DIST_POINTS_ROOF)
- {
- if (!extract_object(crlDistributionPointsObjects, &objectID, &object, &level, &ctx))
- {
- return;
- }
- if (objectID == CRL_DIST_POINTS_FULLNAME)
- {
- /* append extracted generalNames to existing chained list */
- x509_parse_generalNames(object, level+1, TRUE, list);
-
- }
- objectID++;
- }
-}
-
-
-/**
- * Parses an X.509v3 certificate
- */
-static bool parse_certificate(chunk_t blob, u_int level0, private_x509_t *this)
-{
- asn1_ctx_t ctx;
- bool critical;
- chunk_t object;
- u_int level;
- int objectID = 0;
- int extn_oid = OID_UNKNOWN;
-
- asn1_init(&ctx, blob, level0, FALSE, FALSE);
- while (objectID < X509_OBJ_ROOF)
- {
- if (!extract_object(certObjects, &objectID, &object, &level, &ctx))
- {
- return FALSE;
- }
-
- /* those objects which will parsed further need the next higher level */
- level++;
-
- switch (objectID)
- {
- case X509_OBJ_CERTIFICATE:
- this->certificate = object;
- break;
- case X509_OBJ_TBS_CERTIFICATE:
- this->tbsCertificate = object;
- break;
- case X509_OBJ_VERSION:
- this->version = (object.len) ? (1+(u_int)*object.ptr) : 1;
- DBG2(" v%d", this->version);
- break;
- case X509_OBJ_SERIAL_NUMBER:
- this->serialNumber = object;
- break;
- case X509_OBJ_SIG_ALG:
- this->signatureAlgorithm = parse_algorithmIdentifier(object, level, NULL);
- break;
- case X509_OBJ_ISSUER:
- this->issuer = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", this->issuer);
- break;
- case X509_OBJ_NOT_BEFORE:
- this->notBefore = parse_time(object, level);
- break;
- case X509_OBJ_NOT_AFTER:
- this->notAfter = parse_time(object, level);
- break;
- case X509_OBJ_SUBJECT:
- this->subject = identification_create_from_encoding(ID_DER_ASN1_DN, object);
- DBG2(" '%D'", this->subject);
- break;
- case X509_OBJ_SUBJECT_PUBLIC_KEY_ALGORITHM:
- if (parse_algorithmIdentifier(object, level, NULL) != OID_RSA_ENCRYPTION)
- {
- DBG1(" unsupported public key algorithm");
- return FALSE;
- }
- break;
- case X509_OBJ_SUBJECT_PUBLIC_KEY:
- if (ctx.blobs[4].len > 0 && *ctx.blobs[4].ptr == 0x00)
- {
- /* skip initial bit string octet defining 0 unused bits */
- ctx.blobs[4].ptr++; ctx.blobs[4].len--;
- }
- else
- {
- DBG1(" invalid RSA public key format");
- return FALSE;
- }
- break;
- case X509_OBJ_RSA_PUBLIC_KEY:
- this->subjectPublicKey = object;
- break;
- case X509_OBJ_EXTN_ID:
- extn_oid = known_oid(object);
- break;
- case X509_OBJ_CRITICAL:
- critical = object.len && *object.ptr;
- DBG2(" %s", critical ? "TRUE" : "FALSE");
- break;
- case X509_OBJ_EXTN_VALUE:
- {
- switch (extn_oid)
- {
- case OID_SUBJECT_KEY_ID:
- this->subjectKeyID = chunk_clone(parse_keyIdentifier(object, level, FALSE));
- break;
- case OID_SUBJECT_ALT_NAME:
- x509_parse_generalNames(object, level, FALSE, this->subjectAltNames);
- break;
- case OID_BASIC_CONSTRAINTS:
- this->isCA = parse_basicConstraints(object, level);
- break;
- case OID_CRL_DISTRIBUTION_POINTS:
- parse_crlDistributionPoints(object, level, this->crlDistributionPoints);
- break;
- case OID_AUTHORITY_KEY_ID:
- x509_parse_authorityKeyIdentifier(object, level,
- &this->authKeyID, &this->authKeySerialNumber);
- break;
- case OID_AUTHORITY_INFO_ACCESS:
- parse_authorityInfoAccess(object, level, this->ocspAccessLocations);
- break;
- case OID_EXTENDED_KEY_USAGE:
- this->isOcspSigner = parse_extendedKeyUsage(object, level);
- break;
- case OID_NS_REVOCATION_URL:
- case OID_NS_CA_REVOCATION_URL:
- case OID_NS_CA_POLICY_URL:
- case OID_NS_COMMENT:
- if (!parse_asn1_simple_object(&object, ASN1_IA5STRING , level, oid_names[extn_oid].name))
- return FALSE;
- break;
- default:
- break;
- }
- break;
- }
- case X509_OBJ_ALGORITHM:
- {
- int alg = parse_algorithmIdentifier(object, level, NULL);
-
- if (alg != this->signatureAlgorithm)
- {
- DBG1(" signature algorithms do not agree");
- return FALSE;
- }
- }
- break;
- case X509_OBJ_SIGNATURE:
- this->signature = object;
- break;
- default:
- break;
- }
- objectID++;
- }
-
- /* generate the subjectKeyID if it is missing in the certificate */
- if (this->subjectKeyID.ptr == NULL)
- {
- hasher_t *hasher = hasher_create(HASH_SHA1);
-
- hasher->allocate_hash(hasher, this->subjectPublicKey, &this->subjectKeyID);
- hasher->destroy(hasher);
- }
-
- this->installed = time(NULL);
- return TRUE;
-}
-
-/**
- * Implements x509_t.is_valid
- */
-static err_t is_valid(const private_x509_t *this, time_t *until)
-{
- time_t current_time = time(NULL);
-
- DBG2(" not before : %T", &this->notBefore);
- DBG2(" current time: %T", &current_time);
- DBG2(" not after : %T", &this->notAfter);
-
- if (until != NULL &&
- (*until == UNDEFINED_TIME || this->notAfter < *until))
- {
- *until = this->notAfter;
- }
- if (current_time < this->notBefore)
- {
- return "is not valid yet";
- }
- if (current_time > this->notAfter)
- {
- return "has expired";
- }
- DBG2(" certificate is valid");
- return NULL;
-}
-
-/**
- * Implements x509_t.is_ca
- */
-static bool is_ca(const private_x509_t *this)
-{
- return this->isCA;
-}
-
-/**
- * Implements x509_t.is_ocsp_signer
- */
-static bool is_ocsp_signer(const private_x509_t *this)
-{
- return this->isOcspSigner;
-}
-
-/**
- * Implements x509_t.is_self_signed
- */
-static bool is_self_signed(const private_x509_t *this)
-{
- return this->isSelfSigned;
-}
-
-/**
- * Implements x509_t.equals_subjectAltName
- */
-static bool equals_subjectAltName(const private_x509_t *this, identification_t *id)
-{
- bool found = FALSE;
- identification_t *subjectAltName;
- iterator_t *iterator;
-
- iterator = this->subjectAltNames->create_iterator(this->subjectAltNames, TRUE);
- while (iterator->iterate(iterator, (void**)&subjectAltName))
- {
- if (id->equals(id, subjectAltName))
- {
- found = TRUE;
- break;
- }
- }
- iterator->destroy(iterator);
- return found;
-}
-
-/**
- * Implements x509_t.is_issuer
- */
-static bool is_issuer(const private_x509_t *this, const private_x509_t *issuer)
-{
- return (this->authKeyID.ptr)
- ? chunk_equals(this->authKeyID, issuer->subjectKeyID)
- : (this->issuer->equals(this->issuer, issuer->subject)
- && chunk_equals_or_null(this->authKeySerialNumber, issuer->serialNumber));
-}
-
-/**
- * Implements x509_t.get_certificate
- */
-static chunk_t get_certificate(const private_x509_t *this)
-{
- return this->certificate;
-}
-
-/**
- * Implements x509_t.get_public_key
- */
-static rsa_public_key_t *get_public_key(const private_x509_t *this)
-{
- return this->public_key;
-}
-
-/**
- * Implements x509_t.get_serialNumber
- */
-static chunk_t get_serialNumber(const private_x509_t *this)
-{
- return this->serialNumber;
-}
-
-/**
- * Implements x509_t.get_subjectKeyID
- */
-static chunk_t get_subjectKeyID(const private_x509_t *this)
-{
- return this->subjectKeyID;
-}
-
-/**
- * Implements x509_t.get_keyid
- */
-static chunk_t get_keyid(const private_x509_t *this)
-{
- return this->public_key->get_keyid(this->public_key);
-}
-
-/**
- * Implements x509_t.get_issuer
- */
-static identification_t *get_issuer(const private_x509_t *this)
-{
- return this->issuer;
-}
-
-/**
- * Implements x509_t.get_subject
- */
-static identification_t *get_subject(const private_x509_t *this)
-{
- return this->subject;
-}
-
-/**
- * Implements x509_t.set_ca_info
- */
-static void set_ca_info(private_x509_t *this, ca_info_t *ca_info)
-{
- this->ca_info = ca_info;
-}
-
-/**
- * Implements x509_t.get_ca_info
- */
-static ca_info_t *get_ca_info(const private_x509_t *this)
-{
- return this->ca_info;
-}
-
-/**
- * Implements x509_t.set_until
- */
-static void set_until(private_x509_t *this, time_t until)
-{
- this->until = until;
-}
-
-/**
- * Implements x509_t.get_until
- */
-static time_t get_until(const private_x509_t *this)
-{
- return this->until;
-}
-
-/**
- * Implements x509_t.set_status
- */
-static void set_status(private_x509_t *this, cert_status_t status)
-{
- this->status = status;
-}
-
-/**
- * Implements x509_t.get_status
- */
-static cert_status_t get_status(const private_x509_t *this)
-{
- return this->status;
-}
-
-/**
- * Implements x509_t.add_authority_flags
- */
-static void add_authority_flags(private_x509_t *this, u_int flags)
-{
- this->authority_flags |= flags;
-}
-
-/**
- * Implements x509_t.add_authority_flags
- */
-static u_int get_authority_flags(private_x509_t *this)
-{
- return this->authority_flags;
-}
-
-/**
- * Implements x509_t.has_authority_flag
- */
-static bool has_authority_flag(private_x509_t *this, u_int flags)
-{
- return (this->authority_flags & flags) != AUTH_NONE;
-}
-
-/**
- * Implements x509_t.create_crluri_iterator
- */
-static iterator_t *create_crluri_iterator(const private_x509_t *this)
-{
- return this->crlDistributionPoints->create_iterator(this->crlDistributionPoints, TRUE);
-}
-
-/**
- * Implements x509_t.create_crluri_iterator
- */
-static iterator_t *create_ocspuri_iterator(const private_x509_t *this)
-{
- return this->ocspAccessLocations->create_iterator(this->ocspAccessLocations, TRUE);
-}
-
-/**
- * Implements x509_t.verify
- */
-static bool verify(const private_x509_t *this, const rsa_public_key_t *signer)
-{
- hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->signatureAlgorithm);
-
- if (algorithm == HASH_UNKNOWN)
- {
- DBG1(" unknown signature algorithm");
- return FALSE;
- }
- return signer->verify_emsa_pkcs1_signature(signer, algorithm, this->tbsCertificate, this->signature) == SUCCESS;
-}
-
-/**
- * Implementation of x509_t.list.
- */
-static void list(private_x509_t *this, FILE *out, bool utc)
-{
- iterator_t *iterator;
- time_t now = time(NULL);
-
- fprintf(out, "%#T\n", &this->installed, utc);
-
- if (this->subjectAltNames->get_count(this->subjectAltNames))
- {
- identification_t *subjectAltName;
- bool first = TRUE;
-
- fprintf(out, " altNames: ");
- iterator = this->subjectAltNames->create_iterator(this->subjectAltNames, TRUE);
- while (iterator->iterate(iterator, (void**)&subjectAltName))
- {
- if (first)
- {
- first = FALSE;
- }
- else
- {
- fprintf(out, ", ");
- }
- fprintf(out, "'%D'", subjectAltName);
- }
- iterator->destroy(iterator);
- fprintf(out, "\n");
- }
- fprintf(out, " subject: '%D'\n", this->subject);
- fprintf(out, " issuer: '%D'\n", this->issuer);
- fprintf(out, " serial: %#B\n", &this->serialNumber);
- fprintf(out, " validity: not before %#T, ", &this->notBefore, utc);
- if (now < this->notBefore)
- {
- fprintf(out, "not valid yet (valid in %#V)\n", &now, &this->notBefore);
- }
- else
- {
- fprintf(out, "ok\n");
- }
-
- fprintf(out, " not after %#T, ", &this->notAfter, utc);
- if (now > this->notAfter)
- {
- fprintf(out, "expired (%#V ago)\n", &now, &this->notAfter);
- }
- else
- {
- fprintf(out, "ok");
- if (now > this->notAfter - CERT_WARNING_INTERVAL * 60 * 60 * 24)
- {
- fprintf(out, " (expires in %#V)", &now, &this->notAfter);
- }
- fprintf(out, " \n");
- }
-
- {
- chunk_t keyid = this->public_key->get_keyid(this->public_key);
- fprintf(out, " keyid: %#B\n", &keyid);
- }
-
- if (this->subjectKeyID.ptr)
- {
- fprintf(out, " subjkey: %#B\n", &this->subjectKeyID);
- }
- if (this->authKeyID.ptr)
- {
- fprintf(out, " authkey: %#B\n", &this->authKeyID);
- }
- if (this->authKeySerialNumber.ptr)
- {
- fprintf(out, " aserial: %#B\n", &this->authKeySerialNumber);
- }
-
- fprintf(out, " pubkey: RSA %d bits", BITS_PER_BYTE *
- this->public_key->get_keysize(this->public_key));
- fprintf(out, ", status %N",
- cert_status_names, this->status);
-
- switch (this->status)
- {
- case CERT_GOOD:
- fprintf(out, " until %#T", &this->until, utc);
- break;
- case CERT_REVOKED:
- fprintf(out, " on %#T", &this->until, utc);
- break;
- case CERT_UNKNOWN:
- case CERT_UNDEFINED:
- case CERT_UNTRUSTED:
- default:
- break;
- }
-}
-
-/**
- * Implements x509_t.add_subjectAltNames.
- */
-static void add_subjectAltNames(private_x509_t *this, linked_list_t *subjectAltNames)
-{
- iterator_t *iterator = subjectAltNames->create_iterator(subjectAltNames, TRUE);
- identification_t *name = NULL;
-
- while (iterator->iterate(iterator, (void**)&name))
- {
- name = name->clone(name);
- this->subjectAltNames->insert_last(this->subjectAltNames, (void*)name);
- }
- iterator->destroy(iterator);
-}
-
-/*
- * Defined in header.
- */
-chunk_t x509_build_generalNames(linked_list_t *list)
-{
- linked_list_t *generalNames = linked_list_create();
- iterator_t *iterator = list->create_iterator(list, TRUE);
- identification_t *name;
- chunk_t names = chunk_empty;
- size_t len = 0;
-
- while (iterator->iterate(iterator, (void**)&name))
- {
- asn1_t asn1_type = ASN1_EOC;
- chunk_t *generalName;
-
- switch (name->get_type(name))
- {
- case ID_RFC822_ADDR:
- asn1_type = ASN1_CONTEXT_S_1;
- break;
- case ID_FQDN:
- asn1_type = ASN1_CONTEXT_S_2;
- break;
- case ID_DER_ASN1_DN:
- asn1_type = ASN1_CONTEXT_C_4;
- break;
- case ID_DER_ASN1_GN_URI:
- asn1_type = ASN1_CONTEXT_S_6;
- break;
- case ID_IPV4_ADDR:
- case ID_IPV6_ADDR:
- asn1_type = ASN1_CONTEXT_S_7;
- break;
- default:
- continue;
- }
-
- generalName = malloc_thing(chunk_t);
- *generalName = asn1_simple_object(asn1_type, name->get_encoding(name));
- len += generalName->len;
- generalNames->insert_last(generalNames, (void*)generalName);
- }
- iterator->destroy(iterator);
-
- if (len > 0)
- {
- iterator_t *iterator = generalNames->create_iterator(generalNames, TRUE);
- chunk_t *generalName;
- u_char *pos = build_asn1_object(&names, ASN1_SEQUENCE, len);
-
- while (iterator->iterate(iterator, (void**)&generalName))
- {
- memcpy(pos, generalName->ptr, generalName->len);
- pos += generalName->len;
- free(generalName->ptr);
- free(generalName);
- }
- iterator->destroy(iterator);
- }
- generalNames->destroy(generalNames);
- return names;
-}
-
-/*
- * Defined in header.
- */
-chunk_t x509_build_subjectAltNames(linked_list_t *list)
-{
- chunk_t generalNames = x509_build_generalNames(list);
-
- if (generalNames.len)
- {
- return asn1_wrap(ASN1_SEQUENCE, "cm",
- ASN1_subjectAltName_oid,
- asn1_wrap(ASN1_OCTET_STRING, "m", generalNames)
- );
- }
- else
- {
- return chunk_empty;
- }
-}
-
-/**
- * Build a to-be-signed X.509 certificate body
- */
-static chunk_t x509_build_tbs(private_x509_t *this)
-{
- /* version is always X.509v3 */
- chunk_t version = asn1_simple_object(ASN1_CONTEXT_C_0, ASN1_INTEGER_2);
-
- chunk_t extensions = chunk_empty;
-
- if (this->subjectAltNames->get_count(this->subjectAltNames))
- {
- extensions = asn1_wrap(ASN1_CONTEXT_C_3, "m",
- asn1_wrap(ASN1_SEQUENCE, "m",
- x509_build_subjectAltNames(this->subjectAltNames)));
- }
-
- return asn1_wrap(ASN1_SEQUENCE, "mmccmcmm",
- version,
- asn1_simple_object(ASN1_INTEGER, this->serialNumber),
- asn1_algorithmIdentifier(this->signatureAlgorithm),
- this->issuer->get_encoding(this->issuer),
- asn1_wrap(ASN1_SEQUENCE, "mm",
- timetoasn1(&this->notBefore, ASN1_UTCTIME),
- timetoasn1(&this->notAfter, ASN1_UTCTIME)
- ),
- this->subject->get_encoding(this->subject),
- this->public_key->get_publicKeyInfo(this->public_key),
- extensions
- );
-}
-
-/**
- * Implementation of x509_t.build_encoding.
- */
-static void build_encoding(private_x509_t *this, hash_algorithm_t alg,
- rsa_private_key_t *private_key)
-{
- chunk_t signature;
-
- this->signatureAlgorithm = hasher_signature_algorithm_to_oid(alg);
- this->tbsCertificate = x509_build_tbs(this);
- private_key->build_emsa_pkcs1_signature(private_key, alg,
- this->tbsCertificate, &signature);
- this->signature = asn1_bitstring("m", signature);
- this->certificate = asn1_wrap(ASN1_SEQUENCE, "mcm",
- this->tbsCertificate,
- asn1_algorithmIdentifier(this->signatureAlgorithm),
- this->signature);
-
-}
-
-/**
- * Implements x509_t.destroy
- */
-static void destroy(private_x509_t *this)
-{
- this->subjectAltNames->destroy_offset(this->subjectAltNames,
- offsetof(identification_t, destroy));
- this->crlDistributionPoints->destroy_offset(this->crlDistributionPoints,
- offsetof(identification_t, destroy));
- this->ocspAccessLocations->destroy_offset(this->ocspAccessLocations,
- offsetof(identification_t, destroy));
- DESTROY_IF(this->issuer);
- DESTROY_IF(this->subject);
- DESTROY_IF(this->public_key);
- free(this->subjectKeyID.ptr);
- free(this->certificate.ptr);
- free(this);
-}
-
-/**
- * Internal generic constructor
- */
-static private_x509_t *x509_create_empty(void)
-{
- private_x509_t *this = malloc_thing(private_x509_t);
-
- /* initialize */
- this->subjectPublicKey = chunk_empty;
- this->public_key = NULL;
- this->subject = NULL;
- this->issuer = NULL;
- this->ca_info = NULL;
- this->subjectAltNames = linked_list_create();
- this->crlDistributionPoints = linked_list_create();
- this->ocspAccessLocations = linked_list_create();
- this->subjectKeyID = chunk_empty;
- this->authKeyID = chunk_empty;
- this->authKeySerialNumber = chunk_empty;
- this->authority_flags = AUTH_NONE;
- this->isCA = FALSE;
- this->isOcspSigner = FALSE;
-
- /* public functions */
- this->public.equals = (bool (*) (const x509_t*,const x509_t*))equals;
- this->public.equals_subjectAltName = (bool (*) (const x509_t*,identification_t*))equals_subjectAltName;
- this->public.is_issuer = (bool (*) (const x509_t*,const x509_t*))is_issuer;
- this->public.is_valid = (err_t (*) (const x509_t*,time_t*))is_valid;
- this->public.is_ca = (bool (*) (const x509_t*))is_ca;
- this->public.is_self_signed = (bool (*) (const x509_t*))is_self_signed;
- this->public.is_ocsp_signer = (bool (*) (const x509_t*))is_ocsp_signer;
- this->public.get_certificate = (chunk_t (*) (const x509_t*))get_certificate;
- this->public.get_public_key = (rsa_public_key_t* (*) (const x509_t*))get_public_key;
- this->public.get_serialNumber = (chunk_t (*) (const x509_t*))get_serialNumber;
- this->public.get_subjectKeyID = (chunk_t (*) (const x509_t*))get_subjectKeyID;
- this->public.get_keyid = (chunk_t (*) (const x509_t*))get_keyid;
- this->public.get_issuer = (identification_t* (*) (const x509_t*))get_issuer;
- this->public.get_subject = (identification_t* (*) (const x509_t*))get_subject;
- this->public.set_ca_info = (void (*) (x509_t*,ca_info_t*))set_ca_info;
- this->public.get_ca_info = (ca_info_t* (*) (const x509_t*))get_ca_info;
- this->public.set_until = (void (*) (x509_t*,time_t))set_until;
- this->public.get_until = (time_t (*) (const x509_t*))get_until;
- this->public.set_status = (void (*) (x509_t*,cert_status_t))set_status;
- this->public.get_status = (cert_status_t (*) (const x509_t*))get_status;
- this->public.add_authority_flags = (void (*) (x509_t*,u_int))add_authority_flags;
- this->public.get_authority_flags = (u_int (*) (x509_t*))get_authority_flags;
- this->public.has_authority_flag = (bool (*) (x509_t*,u_int))has_authority_flag;
- this->public.create_crluri_iterator = (iterator_t* (*) (const x509_t*))create_crluri_iterator;
- this->public.create_ocspuri_iterator = (iterator_t* (*) (const x509_t*))create_ocspuri_iterator;
- this->public.verify = (bool (*) (const x509_t*,const rsa_public_key_t*))verify;
- this->public.list = (void (*) (x509_t*, FILE *out, bool utc))list;
- this->public.add_subjectAltNames = (void (*) (x509_t*,linked_list_t*))add_subjectAltNames;
- this->public.build_encoding = (void (*) (x509_t*,hash_algorithm_t,rsa_private_key_t*))build_encoding;
- this->public.destroy = (void (*) (x509_t*))destroy;
-
- return this;
-}
-
-/*
- * Described in header.
- */
-x509_t *x509_create(chunk_t serialNumber, identification_t *issuer,
- time_t notBefore, time_t notAfter,
- identification_t *subject,
- rsa_public_key_t *public_key)
-{
- private_x509_t *this = x509_create_empty();
-
- this->serialNumber = serialNumber;
- this->issuer = issuer->clone(issuer);
- this->notBefore = notBefore;
- this->notAfter = notAfter;
- this->subject = subject->clone(subject);
- this->public_key = public_key->clone(public_key);
-
- return &this->public;
-}
-
-/*
- * Described in header.
- */
-x509_t *x509_create_from_chunk(chunk_t chunk, u_int level)
-{
- private_x509_t *this = x509_create_empty();
-
- if (!parse_certificate(chunk, level, this))
- {
- destroy(this);
- return NULL;
- }
-
- /* extract public key from certificate */
- this->public_key = rsa_public_key_create_from_chunk(this->subjectPublicKey);
- if (this->public_key == NULL)
- {
- destroy(this);
- return NULL;
- }
-
- /* set trusted lifetime of public key to notAfter */
- this->until = this->notAfter;
-
- /* check if the certificate is self-signed */
- this->isSelfSigned = FALSE;
- if (this->subject->equals(this->subject, this->issuer))
- {
- hash_algorithm_t algorithm = hasher_algorithm_from_oid(this->signatureAlgorithm);
-
- if (algorithm == HASH_UNKNOWN)
- {
- destroy(this);
- return NULL;
- }
- this->isSelfSigned = this->public_key->verify_emsa_pkcs1_signature(this->public_key,
- algorithm, this->tbsCertificate, this->signature) == SUCCESS;
- }
- if (this->isSelfSigned)
- {
- DBG2(" certificate is self-signed");
- this->status = CERT_GOOD;
- }
- else
- {
- this->status = CERT_UNDEFINED;
- }
-
- return &this->public;
-}
-
-/*
- * Described in header.
- */
-x509_t *x509_create_from_file(const char *filename, const char *label)
-{
- bool pgp = FALSE;
- chunk_t chunk = chunk_empty;
- char cert_label[BUF_LEN];
-
- snprintf(cert_label, BUF_LEN, "%s certificate", label);
-
- if (!pem_asn1_load_file(filename, NULL, cert_label, &chunk, &pgp))
- {
- return NULL;
- }
- return x509_create_from_chunk(chunk, 0);
-}
diff --git a/src/libstrongswan/crypto/x509.h b/src/libstrongswan/crypto/x509.h
deleted file mode 100755
index def45be6b..000000000
--- a/src/libstrongswan/crypto/x509.h
+++ /dev/null
@@ -1,406 +0,0 @@
-/**
- * @file x509.h
- *
- * @brief Interface of x509_t.
- *
- */
-
-/*
- * Copyright (C) 2000 Andreas Hess, Patric Lichtsteiner, Roger Wegmann
- * Copyright (C) 2001 Marco Bertossa, Andreas Schleiss
- * Copyright (C) 2002 Mario Strasser
- * Copyright (C) 2006 Martin Willi
- * Copyright (C) 2000-2008 Andreas Steffen
- *
- * Hochschule fuer Technik Rapperswil
- *
- * 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 of the License, or (at your
- * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
- *
- * 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.
- *
- * RCSID $Id: x509.h 3421 2008-01-22 01:09:19Z andreas $
- */
-
-#ifndef X509_H_
-#define X509_H_
-
-typedef struct x509_t x509_t;
-
-#include <library.h>
-#include <crypto/rsa/rsa_private_key.h>
-#include <crypto/hashers/hasher.h>
-#include <crypto/certinfo.h>
-#include <crypto/ca.h>
-#include <utils/identification.h>
-#include <utils/iterator.h>
-#include <utils/linked_list.h>
-
-/* authority flags */
-
-#define AUTH_NONE 0x00 /* no authorities */
-#define AUTH_CA 0x01 /* certification authority */
-#define AUTH_AA 0x02 /* authorization authority */
-#define AUTH_OCSP 0x04 /* ocsp signing authority */
-
-/**
- * @brief X.509 certificate.
- *
- * @b Constructors:
- * - x509_create()
- * - x509_create_from_chunk()
- * - x509_create_from_file()
- *
- * @ingroup crypto
- */
-struct x509_t {
-
- /**
- * @brief Set trusted public key life.
- *
- * @param this calling object
- * @param until time until public key is trusted
- */
- void (*set_until) (x509_t *this, time_t until);
-
- /**
- * @brief Get trusted public key life.
- *
- * @param this calling object
- * @return time until public key is trusted
- */
- time_t (*get_until) (const x509_t *this);
-
- /**
- * @brief Set the certificate status
- *
- * @param this calling object
- * @param status certificate status
- */
- void (*set_status) (x509_t *this, cert_status_t status);
-
- /**
- * @brief Get the certificate status
- *
- * @param this calling object
- * @return certificate status
- */
- cert_status_t (*get_status) (const x509_t *this);
-
- /**
- * @brief Add authority flags
- *
- * @param this calling object
- * @param flag flags to be added
- */
- void (*add_authority_flags) (x509_t *this, u_int flags);
-
- /**
- * @brief Get authority flags
- *
- * @param this calling object
- * @return authority flags
- */
- u_int (*get_authority_flags) (x509_t *this);
-
- /**
- * @brief Check a specific authority flag
- *
- * @param this calling object
- * @param flag flag to be checked
- * @return TRUE if flag is present
- */
- bool (*has_authority_flag) (x509_t *this, u_int flag);
-
- /**
- * @brief Get the DER-encoded X.509 certificate body
- *
- * @param this calling object
- * @return DER-encoded X.509 certificate
- */
- chunk_t (*get_certificate) (const x509_t *this);
-
- /**
- * @brief Get the RSA public key from the certificate.
- *
- * @param this calling object
- * @return public_key
- */
- rsa_public_key_t *(*get_public_key) (const x509_t *this);
-
- /**
- * @brief Get serial number from the certificate.
- *
- * @param this calling object
- * @return serialNumber
- */
- chunk_t (*get_serialNumber) (const x509_t *this);
-
- /**
- * @brief Get subjectKeyID from the certificate.
- *
- * @param this calling object
- * @return subjectKeyID
- */
- chunk_t (*get_subjectKeyID) (const x509_t *this);
-
- /**
- * @brief Get keyid from the certificate's public key.
- *
- * @param this calling object
- * @return keyid
- */
- chunk_t (*get_keyid) (const x509_t *this);
-
- /**
- * @brief Get the issuerDistinguishedName
- *
- * The resulting ID is always a identification_t
- * of type ID_DER_ASN1_DN.
- *
- * @param this calling object
- * @return issuers ID
- */
- identification_t *(*get_issuer) (const x509_t *this);
-
- /**
- * @brief Get the subjectDistinguishedName.
- *
- * The resulting ID is always a identification_t
- * of type ID_DER_ASN1_DN.
- *
- * @param this calling object
- * @return subjects ID
- */
- identification_t *(*get_subject) (const x509_t *this);
-
- /**
- * @brief Set a link ca info
- *
- * @param this calling object
- * @param ca_info link to the info record of the issuing ca
- */
- void (*set_ca_info) (x509_t *this, ca_info_t *ca_info);
-
- /**
- * @brief Get the .
- *
- * The resulting ID is always a identification_t
- * of type ID_DER_ASN1_DN.
- *
- * @param this calling object
- * @return link to the info record of the issuing ca
- * or NULL if it does not [yet] exist
- */
- ca_info_t *(*get_ca_info) (const x509_t *this);
-
- /**
- * @brief Create an iterator for the crlDistributionPoints.
- *
- * @param this calling object
- * @return iterator for crlDistributionPoints
- */
- iterator_t *(*create_crluri_iterator) (const x509_t *this);
-
- /**
- * @brief Create an iterator for the ocspAccessLocations.
- *
- * @param this calling object
- * @return iterator for ocspAccessLocations
- */
- iterator_t *(*create_ocspuri_iterator) (const x509_t *this);
-
- /**
- * @brief Check if a certificate is trustworthy
- *
- * @param this calling object
- * @param signer signer's RSA public key
- */
- bool (*verify) (const x509_t *this, const rsa_public_key_t *signer);
-
- /**
- * @brief Compare two certificates.
- *
- * Comparison is done via the certificates signature.
- *
- * @param this first cert for compare
- * @param other second cert for compare
- * @return TRUE if signature is equal
- */
- bool (*equals) (const x509_t *this, const x509_t *that);
-
- /**
- * @brief Checks if the certificate contains a subjectAltName equal to id.
- *
- * @param this certificate being examined
- * @param id id which is being compared to the subjectAltNames
- * @return TRUE if a match is found
- */
- bool (*equals_subjectAltName) (const x509_t *this, identification_t *id);
-
- /**
- * @brief Checks if the subject of the other cert is the issuer of this cert.
- *
- * @param this certificate
- * @param issuer potential issuer certificate
- * @return TRUE if issuer is found
- */
- bool (*is_issuer) (const x509_t *this, const x509_t *issuer);
-
- /**
- * @brief Checks the validity interval of the certificate
- *
- * @param this certificate being examined
- * @param until until = min(until, notAfter)
- * @return NULL if the certificate is valid
- */
- err_t (*is_valid) (const x509_t *this, time_t *until);
-
- /**
- * @brief Returns the CA basic constraints flag
- *
- * @param this certificate being examined
- * @return TRUE if the CA flag is set
- */
- bool (*is_ca) (const x509_t *this);
-
- /**
- * @brief Returns the OCSPSigner extended key usage flag
- *
- * @param this certificate being examined
- * @return TRUE if the OCSPSigner flag is set
- */
- bool (*is_ocsp_signer) (const x509_t *this);
-
- /**
- * @brief Checks if the certificate is self-signed (subject equals issuer)
- *
- * @param this certificate being examined
- * @return TRUE if self-signed
- */
- bool (*is_self_signed) (const x509_t *this);
-
- /**
- * @brief Log the certificate info to out.
- *
- * @param this calling object
- * @param out stream to write to
- * @param utc TRUE for UTC times, FALSE for local time
- */
- void (*list) (x509_t *this, FILE *out, bool utc);
-
- /**
- * @brief Adds a list of subjectAltNames
- *
- * @param this calling object
- * @param subjectAltNames list of subjectAltNames to be added
- */
- void (*add_subjectAltNames) (x509_t *this, linked_list_t *subjectAltNames);
-
- /**
- * @brief Builds a DER-encoded signed X.509 certificate
- *
- * @param this calling object
- * @param alg hash algorithm used to compute the certificate digest
- * @param private_key RSA private key used to sign the certificate digest
- */
- void (*build_encoding) (x509_t *this, hash_algorithm_t alg, rsa_private_key_t *private_key);
-
- /**
- * @brief Destroys the certificate.
- *
- * @param this certificate to destroy
- */
- void (*destroy) (x509_t *this);
-};
-
-/**
- * @brief Create a X.509 certificate from its components
- *
- * @param serialNumber chunk containing the serialNumber
- * @param issuer issuer distinguished name
- * @param notBefore start date of validity
- * @param notAfter end date of validity
- * @param subject subject distinguished name
- * @param public_key public key
- *
- * @return created x509_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509_t *x509_create(chunk_t serialNumber, identification_t *issuer,
- time_t notBefore, time_t notAfter,
- identification_t *subject,
- rsa_public_key_t *public_key);
-
-/**
- * @brief Read a X.509 certificate from a DER encoded blob.
- *
- * @param chunk chunk containing DER encoded data
- * @return created x509_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509_t *x509_create_from_chunk(chunk_t chunk, u_int level);
-
-/**
- * @brief Read a X.509 certificate from a DER encoded file.
- *
- * @param filename file containing DER encoded data
- * @param label label describing kind of certificate
- * @return created x509_t certificate, or NULL if invalid.
- *
- * @ingroup crypto
- */
-x509_t *x509_create_from_file(const char *filename, const char *label);
-
-/**
- * @brief Parses a DER encoded authorityKeyIdentifier
- *
- * @param blob blob containing DER encoded data
- * @param level0 indicates the current parsing level
- * @param authKeyID assigns the authorityKeyIdentifier
- * @param authKeySerialNumber assigns the authKeySerialNumber
- *
- * @ingroup crypto
- */
-void x509_parse_authorityKeyIdentifier(chunk_t blob, int level0, chunk_t *authKeyID, chunk_t *authKeySerialNumber);
-
-/**
- * @brief Parses DER encoded generalNames
- *
- * @param blob blob containing DER encoded data
- * @param level0 indicates the current parsing level
- * @param implicit implicit coding is used
- * @param list list of decoded generalNames
- *
- * @ingroup crypto
- */
-void x509_parse_generalNames(chunk_t blob, int level0, bool implicit, linked_list_t *list);
-
-/**
- * @brief Builds a DER encoded list of generalNames
- *
- * @param list list of generalNames to be encoded
- * @return DER encoded list of generalNames
- *
- * @ingroup crypto
- */
-chunk_t x509_build_generalNames(linked_list_t *list);
-
-/**
- * @brief Builds a DER encoded list of subjectAltNames
- *
- * @param list list of subjectAltNames to be encoded
- * @return DER encoded list of subjectAltNames
- *
- * @ingroup crypto
- */
-chunk_t x509_build_subjectAltNames(linked_list_t *list);
-
-#endif /* X509_H_ */