Generate Aes-256-ctr Key

It accepts a binary string for the key (ie. NOT encoded), at least for the cipher methods I tried (AES-128-CTR and AES-256-CTR). One of the posts says you should hex encode the key (which is wrong), and some say you should hash the key but don't make it clear how to properly pass the hashed key. Jul 29, 2019 In 2009, they discovered a possible related-key attack. This type of cryptanalysis attempts to crack a cipher by observing how it operates using different keys. Fortunately, the related-key attack is only a threat to AES systems that are incorrectly configured. That same year, there was a known-key distinguishing attack against AES 128.

A short guide to help to avoid the common mistakes and pitfalls with symmetric data encryption using PHP.

This primer assumes “storing data at rest” situation (web server handles the encryption, possibly affected by a web client by providing plaintext/password etc.), which is probably a typical case with PHP applications.

Note, this primer should not be used to construct encrypted network connections which has more complicated needs. For such use cases, consider using spiped or TLS.

Generate Aes-256-ctr Key

Naturally the recommendations given here are not the “only possible way” to handle data encryption in PHP, but this primer aims to be straightforward and tries to leave less room for mistakes and (possibly confusing) choices.

11 May 2016Add mention about random_bytes() which is available in PHP7 and later.
06 Nov 2015Removed Mcrypt mentions from the post (except from random number context).
26 Jun 2014Post revised to mention and warn about encrypted network connections, updated the PHP userland PBKDF2 link.
18 Jun 2014Post title was revised from 'PHP data encryption cheatsheet' to 'PHP data encryption primer'.

Encryption functions available in PHP

Use OpenSSL extension.

Encryption algorithm / mode of operation / nonce (initializing vector)

Use AES-256 in CTR mode with random nonce. AES is the standard and can be used with OpenSSL extension.

Make sure to always generate a new random nonce when encrypting data. This must be done using cryptographically secure randomness source. See more about random number generation here. The nonce can be concatenated with the ciphertext to allow decryption.

The nonce length must be 128 bits (16 bytes) and must contain raw bytes, not encoded in any way.

With OpenSSL, AES is known as AES-256-CTR:

Verify your encryption and decryption routines against AES test vectors.

There are some data length limits with AES in CTR mode. While not probably in practical manner, but keep in mind that you should encrypt less than 2^64 bytes of data with a single key (no matter if it is a “few” smaller messages or just only one big message).

Also, CTR mode is only safe when you do not reuse nonces under a single key. That is why it is important to create the nonces with cryptographically secure random number generator. At the same time it means you must not encrypt more than 2^64 different messages with a single key (as the nonce space with AES is 128 bits, it is important to limit the number of messages (nonces) to 2^128/2 because of the birthday paradox).

And remember that encrypting the data will not hide, most importantly, the fact how much data you are sending. As a drastic example, if you only encrypt messages containing “yes” / “no”, the plain encryption do not hide the confidential details.

Data authentication

Always authenticate the encrypted data.

Use Encrypt-then-MAC construction. That is, first encrypt the data and finally take an HMAC-SHA-256 of the resulted ciphertext, and include all the relevant pieces under the HMAC (namely ciphertext and nonce).

When decrypting, first check the HMAC using a constant-time string comparison (do not directly compare $user_submitted_mac and $calculated_mac with string comparison). Or better yet, compare the strings using “double HMAC verification”. This is to avoid leaking exploitable timing information that occurs on the string comparison.

If the HMAC matches, the ciphertext is safe to feed to decrypt process. If the HMAC does not match, exit immediately.

Encryption and authentication keys

Ideally, use keys generated using cryptographically secure random number generator (see more about random number generation here). With AES-256 you need 32 bytes of random data (raw bytes, not encoded).

If you have to rely on user typed keys (ie. a config parameter), it needs to be stretched to be suitable to use as an encryption key. Use PBKDF2 algorithm to turn a human supplied key into an encryption key. See http://php.net/hash_pbkdf2 (and make sure to use raw output).

If you are not on PHP 5.5 or higher, you have to use an userland PHP PBKDF2 implementation. One such implementation can be found here: https://defuse.ca/php-pbkdf2.htm.

Note that when relying on userland implementations, you can not stretch the key as much as you could with more efficient PHP’s native hash_pbkdf2() function, which means you can not squeeze as much security out of the user supplied key.

Do not use same key for encryption and authentication. As seen above, you need 32 bytes for an encryption key. Use also 32 bytes for an authentication (HMAC) key.

With PBKDF2 you can derive 64 bytes from a single password/master key and use, say, the first 32 bytes for encryption and the last 32 bytes for authentication.

If you have the keys stored in a file, say, hex encoded, do not decode them prior to feeding to the encryption routines. Instead, as earlier mentioned, use PBKDF2 to turn the hex encoded keys into proper encryption/authentication keys. Or use SHA-256 (with raw output) to hash the hex encoded keys and turn them into proper raw bytes (the use of “plain” hashing assumes the initial keys has enough guessing entropy, as explained in the next paragraphs).

Key stretching

Low entropy keys should be avoided in the first place. But if you need to rely on, say, user’s passwords, you need to use as high PBKDF2 iteration count as possible to squeeze as much security as possible out of the passwords.

PBKDF2 algorithm can be adjusted for specific iteration count. The higher the iteration count the higher the security of the derived key. If your code runs on 64-bit platform, use sha512 as the underlying PBKDF2 hashing algorithm. If you are on 32-bit platform, use sha256 as the underlying hashing algorithm.

In general, it is not possible to use relatively high iteration count in online applications (which face the public internet). And thus the added security to the key will not be as high as in more ideal situation (i.e. an offline application could use higher iteration count without the fear of a DoS attack). As a rule of thumb, for online applications, adjust the PBKDF2 iteration count to take less than 100 ms.

If you can use high entropy passwords (or config parameter etc.), you don’t need to stretch them as much as low entropy passwords. For example if you created “master_encryption_key” and “master_authentication_key” using /dev/urandom, you don’t need PBKDF2 necessarily at all. This is because the initial keys contains already enough guessing entropy. Just make sure you input raw bytes to the encryption/authentication routines, as earlier mentioned.

However, it is easy to derive both the encryption and authentication keys with PBKDF2 from the single master password (just use low iteration count, i.e. 1). This is useful if you have only one “master key” which should be derived for both the encryption and authentication use.

Key storage and management

Ideally, use a separate hardware to store keys (i.e. HSM).

If this is not possible, one method to mitigate the attack surface is by encrypting your key file or config file (which holds the actual encryption/authentication keys) with a key stored in a separate location from the actual key file (separate from the home/www folder). For example, you can use an Apache environment variable via httpd.conf to store the key needed to unlock the actual key file:

Now, if your www-root (including your key/config file) leaks i.e. via backup tape, the encrypted data is still safe as long as the keyfile_key environment variable stays secret. Remember to have a separate backup of the httpd.conf file (e.g. in a safe) and make sure you do not leak the keyfile_key via phpinfo().

If you use a specific key file (instead of a config parameter), it is feasible to rotate keys. In the worst-case scenario where an adversary has got your encryption/authentication keys and nobody knows that, rotating the keys by some period of time might cut her access (assuming she can not get the new keys). This may make the damage smaller because the adversary can not abuse the leaked keys endlessly.

Data compression

As a rule of thumb, do not compress plaintext prior to encryption. This might leak information about the plaintext to an adversary.

For example, if you store session data into an encrypted browser cookie, and you store some user submitted data along with some secret data, the adversary can learn about the secret data by sending specially crafted payloads (the user submitted data) and measuring how the ciphertext sizes vary.

This is because the underlying compression is more effective if there are similarities in the user submitted data and the secret data, and thus leaks information via the payload size. CRIME is based on this information leak (side-channel).

If you are in doubt, do not use data compression.

Server environment

As a rule of thumb, do not host your security critical application on a shared hardware (i.e. a VM on a web host where an adversary could host her VM as well on the same physical hardware).

There are different side-channels (among others problems) which makes shared hardware a questionable place to host security critical code. For example, cross-VM attacks has been recently demonstrated: http://eprint.iacr.org/2014/248.pdf. This is a good reminder that attacks never get worse, instead they get better and better over time. Such pitfalls should be always acknowledged.

If in doubt, do not deploy your security critical application to a shared hardware.

Consult an expert

Last but not least, consult an expert to review your security critical code.

@rootlabs, 5. June 2014:

@plo @veorq I have been working in crypto since 1997, and I still get every design or implementation I do reviewed by a 3rd party.

Appendix

Cryptographically safe random numbers

Use operating system provided randomness. In PHP, use random_bytes($count) which is available in PHP7 and later, mcrypt_create_iv($count, MCRYPT_DEV_URANDOM) or manually read from /dev/urandom.

Make sure you get the needed amount of bytes. If not, exit immediately (do not try to recover from an error by falling back to home-made randomness construction).

NAME

openssl - OpenSSL command line program

SYNOPSIS

opensslcommand [ options ... ] [ parameters ... ]

openssllist-standard-commands | -digest-commands | -cipher-commands | -cipher-algorithms | -digest-algorithms | -mac-algorithms | -public-key-algorithms

opensslno-XXX [ options ]

DESCRIPTION

OpenSSL is a cryptography toolkit implementing the Secure Sockets Layer (SSL v2/v3) and Transport Layer Security (TLS v1) network protocols and related cryptography standards required by them.

The openssl program is a command line program for using the various cryptography functions of OpenSSL's crypto library from the shell. It can be used for

COMMAND SUMMARY

The openssl program provides a rich variety of commands (command in the 'SYNOPSIS' above). Each command can have many options and argument parameters, shown above as options and parameters.

Detailed documentation and use cases for most standard subcommands are available (e.g., openssl-x509(1)).

The list options -standard-commands, -digest-commands, and -cipher-commands output a list (one entry per line) of the names of all standard commands, message digest commands, or cipher commands, respectively, that are available.

The list parameters -cipher-algorithms, -digest-algorithms, and -mac-algorithms list all cipher, message digest, and message authentication code names, one entry per line. Aliases are listed as:

The list parameter -public-key-algorithms lists all supported public key algorithms.

The command no-XXX tests whether a command of the specified name is available. If no command named XXX exists, it returns 0 (success) and prints no-XXX; otherwise it returns 1 and prints XXX. In both cases, the output goes to stdout and nothing is printed to stderr. Additional command line arguments are always ignored. Since for each cipher there is a command of the same name, this provides an easy way for shell scripts to test for the availability of ciphers in the openssl program. (no-XXX is not able to detect pseudo-commands such as quit, list, or no-XXX itself.)

Configuration Option

Many commands use an external configuration file for some or all of their arguments and have a -config option to specify that file. The default name of the file is openssl.cnf in the default certificate storage area, which can be determined from the openssl-version(1) command using the -d or -a option. The environment variable OPENSSL_CONF can be used to specify a different file location or to disable loading a configuration (using the empty string).

Among others, the configuration file can be used to load modules and to specify parameters for generating certificates and random numbers. See config(5) for details.

Standard Commands

asn1parse

Parse an ASN.1 sequence.

ca

Certificate Authority (CA) Management.

ciphers

Cipher Suite Description Determination.

cms

CMS (Cryptographic Message Syntax) command.

crl

Certificate Revocation List (CRL) Management.

crl2pkcs7

CRL to PKCS#7 Conversion.

dgst

Message Digest calculation. MAC calculations are superseded by openssl-mac(1).

dhparam

Generation and Management of Diffie-Hellman Parameters. Superseded by openssl-genpkey(1) and openssl-pkeyparam(1).

dsa

DSA Data Management.

dsaparam

DSA Parameter Generation and Management. Superseded by openssl-genpkey(1) and openssl-pkeyparam(1).

ec

EC (Elliptic curve) key processing.

ecparam

EC parameter manipulation and generation.

enc

Encryption, decryption, and encoding.

engine

Engine (loadable module) information and manipulation.

errstr

Error Number to Error String Conversion.

fipsinstall

FIPS configuration installation.

gendsa

Generation of DSA Private Key from Parameters. Superseded by openssl-genpkey(1) and openssl-pkey(1).

genpkey

Generation of Private Key or Parameters.

genrsa

Generation of RSA Private Key. Superseded by openssl-genpkey(1).

help

Display information about a command's options.

info

Display diverse information built into the OpenSSL libraries.

kdf

Key Derivation Functions.

list

List algorithms and features.

mac

Message Authentication Code Calculation.

nseq

Create or examine a Netscape certificate sequence.

ocsp

Online Certificate Status Protocol command.

passwd

Generation of hashed passwords.

pkcs12

PKCS#12 Data Management.

pkcs7
Generate Aes-256-ctr Key

PKCS#7 Data Management.

pkcs8

PKCS#8 format private key conversion command.

pkey

Public and private key management.

pkeyparam

Public key algorithm parameter management.

pkeyutl

Public key algorithm cryptographic operation command.

prime

Compute prime numbers.

rand

Generate pseudo-random bytes.

rehash

Create symbolic links to certificate and CRL files named by the hash values.

req

PKCS#10 X.509 Certificate Signing Request (CSR) Management.

rsa

RSA key management.

rsautl

RSA command for signing, verification, encryption, and decryption. Superseded by openssl-pkeyutl(1).

s_client

This implements a generic SSL/TLS client which can establish a transparent connection to a remote server speaking SSL/TLS. It's intended for testing purposes only and provides only rudimentary interface functionality but internally uses mostly all functionality of the OpenSSL ssl library.

s_server

This implements a generic SSL/TLS server which accepts connections from remote clients speaking SSL/TLS. It's intended for testing purposes only and provides only rudimentary interface functionality but internally uses mostly all functionality of the OpenSSL ssl library. It provides both an own command line oriented protocol for testing SSL functions and a simple HTTP response facility to emulate an SSL/TLS-aware webserver.

s_time

SSL Connection Timer.

sess_id

SSL Session Data Management.

smime

S/MIME mail processing.

speed

Algorithm Speed Measurement.

spkac

SPKAC printing and generating command.

srp

Maintain SRP password file. This command is deprecated.

storeutl

Command to list and display certificates, keys, CRLs, etc.

ts

Time Stamping Authority command.

verify

X.509 Certificate Verification. See also the openssl-verification-options(1) manual page.

version

OpenSSL Version Information.

x509

X.509 Certificate Data Management.

Message Digest Commands

blake2b512

BLAKE2b-512 Digest

blake2s256

BLAKE2s-256 Digest

md2

MD2 Digest

md4

MD4 Digest

md5

MD5 Digest

mdc2

MDC2 Digest

rmd160

RMD-160 Digest

sha1

Generate Aes-256-ctr Key Link

SHA-1 Digest

sha224

SHA-2 224 Digest

sha256

SHA-2 256 Digest

sha384

SHA-2 384 Digest

sha512

SHA-2 512 Digest

sha3-224

SHA-3 224 Digest

sha3-256

SHA-3 256 Digest

sha3-384

SHA-3 384 Digest

sha3-512

SHA-3 512 Digest

shake128

SHA-3 SHAKE128 Digest

shake256

SHA-3 SHAKE256 Digest

sm3

SM3 Digest

Encryption, Decryption, and Encoding Commands

The following aliases provide convenient access to the most used encodings and ciphers.

Depending on how OpenSSL was configured and built, not all ciphers listed here may be present. See openssl-enc(1) for more information.

aes128, aes-128-cbc, aes-128-cfb, aes-128-ctr, aes-128-ecb, aes-128-ofb

AES-128 Cipher

aes192, aes-192-cbc, aes-192-cfb, aes-192-ctr, aes-192-ecb, aes-192-ofb

AES-192 Cipher

aes256, aes-256-cbc, aes-256-cfb, aes-256-ctr, aes-256-ecb, aes-256-ofb

AES-256 Cipher

aria128, aria-128-cbc, aria-128-cfb, aria-128-ctr, aria-128-ecb, aria-128-ofb

Aria-128 Cipher

aria192, aria-192-cbc, aria-192-cfb, aria-192-ctr, aria-192-ecb, aria-192-ofb

Aria-192 Cipher

aria256, aria-256-cbc, aria-256-cfb, aria-256-ctr, aria-256-ecb, aria-256-ofb

Aria-256 Cipher

base64

Base64 Encoding

bf, bf-cbc, bf-cfb, bf-ecb, bf-ofb

Blowfish Cipher

camellia128, camellia-128-cbc, camellia-128-cfb, camellia-128-ctr, camellia-128-ecb, camellia-128-ofb

Camellia-128 Cipher

camellia192, camellia-192-cbc, camellia-192-cfb, camellia-192-ctr, camellia-192-ecb, camellia-192-ofb

Camellia-192 Cipher

camellia256, camellia-256-cbc, camellia-256-cfb, camellia-256-ctr, camellia-256-ecb, camellia-256-ofb

Camellia-256 Cipher

cast, cast-cbc

CAST Cipher

cast5-cbc, cast5-cfb, cast5-ecb, cast5-ofb

CAST5 Cipher

chacha20

Chacha20 Cipher

des, des-cbc, des-cfb, des-ecb, des-ede, des-ede-cbc, des-ede-cfb, des-ede-ofb, des-ofb

DES Cipher

des3, desx, des-ede3, des-ede3-cbc, des-ede3-cfb, des-ede3-ofb

Triple-DES Cipher

idea, idea-cbc, idea-cfb, idea-ecb, idea-ofb

IDEA Cipher

Generate Aes-256-ctr Key West

rc2, rc2-cbc, rc2-cfb, rc2-ecb, rc2-ofb

RC2 Cipher

rc4

RC4 Cipher

rc5, rc5-cbc, rc5-cfb, rc5-ecb, rc5-ofb

RC5 Cipher

seed, seed-cbc, seed-cfb, seed-ecb, seed-ofb

SEED Cipher

sm4, sm4-cbc, sm4-cfb, sm4-ctr, sm4-ecb, sm4-ofb

SM4 Cipher

OPTIONS

Details of which options are available depend on the specific command. This section describes some common options with common behavior.

Common Options

-help

Provides a terse summary of all options. If an option takes an argument, the 'type' of argument is also given.

--

This terminates the list of options. It is mostly useful if any filename parameters start with a minus sign:

Format Options

See openssl-format-options(1) for manual page.

Pass Phrase Options

See the openssl-passphrase-options(1) manual page.

Random State Options

Prior to OpenSSL 1.1.1, it was common for applications to store information about the state of the random-number generator in a file that was loaded at startup and rewritten upon exit. On modern operating systems, this is generally no longer necessary as OpenSSL will seed itself from a trusted entropy source provided by the operating system. These flags are still supported for special platforms or circumstances that might require them.

It is generally an error to use the same seed file more than once and every use of -rand should be paired with -writerand.

-randfiles

A file or files containing random data used to seed the random number generator. Multiple files can be specified separated by an OS-dependent character. The separator is ; for MS-Windows, , for OpenVMS, and : for all others. Another way to specify multiple files is to repeat this flag with different filenames.

-writerandfile

Writes the seed data to the specified file upon exit. This file can be used in a subsequent command invocation.

Certificate Verification Options

See the openssl-verification-options(1) manual page.

Name Format Options

See the openssl-namedisplay-options(1) manual page.

TLS Version Options

Several commands use SSL, TLS, or DTLS. By default, the commands use TLS and clients will offer the lowest and highest protocol version they support, and servers will pick the highest version that the client offers that is also supported by the server.

The options below can be used to limit which protocol versions are used, and whether TCP (SSL and TLS) or UDP (DTLS) is used. Note that not all protocols and flags may be available, depending on how OpenSSL was built.

-ssl3, -tls1, -tls1_1, -tls1_2, -tls1_3, -no_ssl3, -no_tls1, -no_tls1_1, -no_tls1_2, -no_tls1_3

These options require or disable the use of the specified SSL or TLS protocols. When a specific TLS version is required, only that version will be offered or accepted. Only one specific protocol can be given and it cannot be combined with any of the no_ options.

-dtls, -dtls1, -dtls1_2

These options specify to use DTLS instead of DLTS. With -dtls, clients will negotiate any supported DTLS protocol version. Use the -dtls1 or -dtls1_2 options to support only DTLS1.0 or DTLS1.2, respectively.

Engine Options

-engineid

Load the engine identified by id and use all the methods it implements (algorithms, key storage, etc.), unless specified otherwise in the command-specific documentation or it is configured to do so, as described in 'Engine Configuration' in config(5).

The engine will be used for key ids specified with -key and similar options when an option like -keyform engine is given.

A special case is the loader_attic engine, which is meant just for internal OpenSSL testing purposes and supports loading keys, parameters, certificates, and CRLs from files. When this engine is used, files with such credentials are read via this engine. Using the file: schema is optional; a plain file (path) name will do.

Options specifying keys, like -key and similar, can use the generic OpenSSL engine key loading URI scheme org.openssl.engine: to retrieve private keys and public keys. The URI syntax is as follows, in simplified form:

Where {engineid} is the identity/name of the engine, and {keyid} is a key identifier that's acceptable by that engine. For example, when using an engine that interfaces against a PKCS#11 implementation, the generic key URI would be something like this (this happens to be an example for the PKCS#11 engine that's part of OpenSC):

As a third possibility, for engines and providers that have implemented their own OSSL_STORE_LOADER(3), org.openssl.engine: should not be necessary. For a PKCS#11 implementation that has implemented such a loader, the PKCS#11 URI as defined in RFC 7512 should be possible to use directly:

Provider Options

-providername

Load and initialize the provider identified by name.

-provider-pathpath

Specifies the search path that is to be used for looking for providers.

-propquerypropq

Specifies the property query clause to be used when fetching algorithms from the loaded providers. See property(7) for a more detailed description.

ENVIRONMENT

The OpenSSL library can be take some configuration parameters from the environment. Some of these variables are listed below. For information about specific commands, see openssl-engine(1), openssl-rehash(1), and tsget(1).

For information about the use of environment variables in configuration, see 'ENVIRONMENT' in config(5).

For information about querying or specifying CPU architecture flags, see OPENSSL_ia32cap(3), and OPENSSL_s390xcap(3).

For information about all environment variables used by the OpenSSL libraries, see openssl-env(7).

OPENSSL_TRACE=name[,...]

Enable tracing output of OpenSSL library, by name. This output will only make sense if you know OpenSSL internals well. Also, it might not give you any output at all, depending on how OpenSSL was built.

The value is a comma separated list of names, with the following available:

TRACE

The tracing functionality.

TLS

General SSL/TLS.

TLS_CIPHER

SSL/TLS cipher.

CONF

Show details about provider and engine configuration.

ENGINE_TABLE

The function that is used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults and functional references (etc), will generate debugging summaries.

ENGINE_REF_COUNT
Generate

Reference counts in the ENGINE structure will be monitored with a line of generated for each change.

PKCS5V2

PKCS#5 v2 keygen.

PKCS12_KEYGEN

PKCS#12 key generation.

PKCS12_DECRYPT

PKCS#12 decryption.

X509V3_POLICY

Generates the complete policy tree at various point during X.509 v3 policy evaluation.

BN_CTX

BIGNUM context.

SEE ALSO

openssl-asn1parse(1), openssl-ca(1), openssl-ciphers(1), openssl-cms(1), openssl-crl(1), openssl-crl2pkcs7(1), openssl-dgst(1), openssl-dhparam(1), openssl-dsa(1), openssl-dsaparam(1), openssl-ec(1), openssl-ecparam(1), openssl-enc(1), openssl-engine(1), openssl-errstr(1), openssl-gendsa(1), openssl-genpkey(1), openssl-genrsa(1), openssl-kdf(1), openssl-mac(1), openssl-nseq(1), openssl-ocsp(1), openssl-passwd(1), openssl-pkcs12(1), openssl-pkcs7(1), openssl-pkcs8(1), openssl-pkey(1), openssl-pkeyparam(1), openssl-pkeyutl(1), openssl-prime(1), openssl-rand(1), openssl-rehash(1), openssl-req(1), openssl-rsa(1), openssl-rsautl(1), openssl-s_client(1), openssl-s_server(1), openssl-s_time(1), openssl-sess_id(1), openssl-smime(1), openssl-speed(1), openssl-spkac(1), openssl-srp(1), openssl-storeutl(1), openssl-ts(1), openssl-verify(1), openssl-version(1), openssl-x509(1), config(5), crypto(7), openssl-env(7). ssl(7), x509v3_config(5)

HISTORY

The list -XXX-algorithms options were added in OpenSSL 1.0.0; For notes on the availability of other commands, see their individual manual pages.

The -issuer_checks option is deprecated as of OpenSSL 1.1.0 and is silently ignored.

The -xcertform and -xkeyform options are obsolete since OpenSSL 3.0 and have no effect.

The interactive mode, which could be invoked by running openssl with no further arguments, was removed in OpenSSL 3.0, and running that program with no arguments is now equivalent to openssl help.

COPYRIGHT

Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the 'License'). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at https://www.openssl.org/source/license.html.