# OpenSSL

OpenSSL is a library for general-purpose cryptography. OpenSSL is also an open-source command line tool that is commonly used to generate private keys, create CSRs, install your SSL/TLS certificate, and identify certificate information.

## Build + Install

{% code overflow="wrap" %}

```bash
#!/bin/bash -xe

#For X86
export ARCH=""
export CROSS_COMPILE=""
export OPENSSL_TARGET=""

#For arm64, source toolchain and set the below config
<<ARM64
export ARCH=arm64
export CROSS_COMPILE="aarch64-linux-gnu-"
export OPENSSL_TARGET=linux-aarch64
ARM64

echo "Download OpenSSL 1.1.1g"
wget https://www.openssl.org/source/openssl-1.1.1g.tar.gz

echo "untaring... openSSL"
tar -xf  openssl-1.1.1g.tar.gz
cd openssl-1.1.1g

echo "Configuring OpenSSL"
./Configure ${OPENSSL_TARGET} shared -pg -fPIC --cross-compile-prefix=$CROSS_COMPILE --prefix=/tmp/openssl11 --openssldir=/tmp/openssl11/etc/ssl

echo "Building ..."
make -j8

echo "Installing ...."
make install_sw DESTDIR=<path to staging dir>
```

{% endcode %}

Successful compilation directs output into 3 directories

```bash
Ubuntu@staging/tmp/openssl11
❯ tree 2
.
├── bin
│   ├── c_rehash
│   └── openssl
├── include
│   └── openssl
└── lib
    ├── engines-1.1
    ├── libcrypto.a
    ├── libcrypto.so -> libcrypto.so.1.1
    ├── libcrypto.so.1.1
    ├── libssl.a
    ├── libssl.so -> libssl.so.1.1
    ├── libssl.so.1.1
    └── pkgconfig

```

```bash
export LD_LIBRARY_PATH=<path till lib dir>
./bin/openssl version -a
```

## Commands

These commands are for "secp384r1" curve. The same applies to other supported curves.

```bash
# check the version of openssl
openssl version -a

# Get a random number
openssl rand -hex 64

# Generate Private key for secp384 curve
openssl ecparam -genkey -name secp384r1 -out privatekey.pem

# Generate Certificate for a given private key 
openssl req -new -sha256 -key privatekey.pem -out csr.csr -subj "/C=US/ST=FL/L=Orlando/O=Foo LLC/OU=IT/CN=www.example.com"

# Generate Public key for given private key and certificate.
openssl req -x509 -sha256 -days 365 -key privatekey.pem -in csr.csr -out publickey.pem

# Start server instance on port 8443
openssl s_server -tls1_3 -accept 8443 -cert publickey.pem -curves secp384r1 -key privatekey.pem

# Connect to the server with the client
openssl s_client -tls1_3 -curves secp384r1 -connect <server_ip>:8443 
```

> * -engine \<engine name>  : Accelarate with specified engine
> * -tls1\_3 : Use TLSv1.3 for communication
> * -quiet: less verbose&#x20;
> * -rand \<path to node > : use the specified random number from node instead of kernel entrophy&#x20;

## API's

#### Leverage custom engine

OpenSSL provides flexibility to offload operations onto custom HW.  The below code leverages the engine to perform all OpenSSL operations

<pre class="language-c"><code class="lang-c">ENGINE_load_builtin_engines();
<strong>ENGINE *e = ENGINE_by_id("engine name");
</strong>// Make the engine's implementations the default implementations
ENGINE_init(e)
ENGINE_set_default_digests(e)
// Set default engine
ENGINE_set_default(e, ENGINE_METHOD_ALL);
// Free the engine
ENGINE_free(e);
ENGINE_cleanup();
</code></pre>

#### Load custom Random numbers

```c
// seed PRNG
if (RAND_load_file("/dev/<node>", 256) < 64) {
      printf("Can't seed PRNG!\n");
      return -1;
}
```

#### Allocate, Initialize and Generate key pair

```c
// Allocates memory for key pair
EC_KEY *eckey=EC_KEY_new();
// Assign curve to the keypair
EC_GROUP *ecgroup= EC_GROUP_new_by_curve_name(NID_secp384r1);
// Map the keypair and curve
set_group_status = EC_KEY_set_group(eckey,ecgroup);
// Generate key pair, it will offload to engine,
// performs 2 PM operations.
gen_status = EC_KEY_generate_key(eckey);

//Free the handlers
EC_GROUP_free(ecgroup);
EC_KEY_free(eckey);
```

#### Sign Key

```c
// Sign the key with given hash
ECDSA_SIG *signature;
signature = ECDSA_do_sign(hash, strlen(hash), eckey);

// Free Signature
ECDSA_SIG_free(signature);
```

#### Verify Signed Key

```c
// Verify Signature
verify_status = ECDSA_do_verify(hash, strlen(hash), signature, eckey);
```

#### Point Multiplication

```c
// Perform point multiplication
ret = EC_POINT_mul(ecgroup, pub_key, privKeyBN, NULL, NULL, ctx);
```

## Engine

OpenSSL provides flexibility to offload operations onto custom HW.\
**openssl** command searches for the custom engine library (so) in

* default : **`/usr/lib/engines-1.1/`**
* OpenSSL : **`<path to openssl>/lib/engines-1.1/`**&#x20;

{% code title="Check Custom Engine" %}

```
openssl engine <engine name>
```

{% endcode %}

{% hint style="info" %}
-engine \<engine name>&#x20;
{% endhint %}

## Benchmarking

```bash
# Benchmark all curves ecdsa operations
openssl speed -elapsed ecdsa

# Benchmark single curve ecdsa operations
openssl speed -elapsed ecdsap384

# Benchmark all curves point multiplication
openssl speed -elapsed ecdh

# Benchmark single curve point multiplication
openssl speed -elapsed ecdhp384
```

> * -elapsed gives wall clock time ( actual time lapse ).\
>   &#x20;Without elapsed it measures only active CPU time.
> * -multi \<n> : runs on multiple instances on multiple cores. &#x20;


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://explore-vineeth.gitbook.io/mywiki/programming/libraries/openssl.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
