Innovation Series

BoringSSL FIPS Mode in Go: Understanding the Overhead

Pankaj Pipada, Senior Technical Director and Arati Joshi, Sr. Principal Engineer

In cryptography, the Federal Information Processing Standard (FIPS) is a standard that defines the security requirements for cryptography algorithms and the software that implements them. It is used by the U.S. federal government and other organizations to ensure that cryptographic systems and solutions are secure and reliable. The BoringSSL library in Go provides support for the FIPS mode. However, the use of the BoringSSL FIPS mode also incurs some overhead compared to when it is not used. In this blog, we will explore the overhead caused by BoringSSL FIPS mode in Go, as well as the impact on overall performance.

How Tests are Performed

We selected the AES-GCM encryption algorithm for our benchmarking. AES (Advanced Encryption Standard) is a FIPS-compliant symmetric encryption algorithm. Symmetric algorithms use the same key for both encryption and decryption. AES can use key lengths of 128, 192, and 256 bits. AES along with Galois/Counter Mode (AES-GCM) provides both confidentiality and authentication. We need to provide a Nonce as input to AES-GCM. Nonce (a number used only once) is a non-repeating sequence that AES-GCM uses internally to generate different keystreams for different messages even if encrypted with that key.

Parameters

We used AES-GCM encryption algorithm and varied the below parameters:

  1. Key size: 128 bits, 256 bits

  2. Nonce size: 12 bytes, 16 bytes

  3. Number of Goroutines running in parallel to perform encryption: 4, 8, 16

  4. Data block size: 1MB

CPU usage and time required to complete one encryption operation are measured.

Code

We used the below code snippet for the test runs. We ran this test in multiple goroutines as per test configuration with the required changes in Nonce length.

Code snippet

Hardware Setup 

  • Linux VM with Cores: 20, Hyperthreading: 0ff

  • CPU specification: Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz

  • AES hardware implementation: enabled

  • OS: Ubuntu 20.04 

Encryption Performance in an Isolated Environment

The below table notes the results after variation of the input parameters for the test.

Key size (bits)

Nonce (bytes)

Parallel goroutines

Latency with BoringSSL (ms)

Cores used with BoringSSL

Latency with Vanilla Go (ms)

Cores used with Vanilla Go

128

12

4

3.2

4

1.2

4

128

16

4

16

4

1.2

4

256

12

4

3.2

4

1.4

4

256

16

4

17

4

1.4

4

128

12

8

5.7

7

1.3

7

128

16

8

25

8

1.4

7

256

12

8

5.8

7

1.5

7

256

16

8

25

8

1.5

7

128

12

16

12.5

8

2.6

7

128

16

16

35

15

2.6

7

256

12

16

13

8

3

7

256

16

16

35

15

3

7

The results of the tests showed that BoringSSL FIPS-enabled Go was slower than Vanilla Go in all cases. For instance, when using a key size of 128 bits and a nonce size of 12 bytes, BoringSSL FIPS-enabled Go took 3.2 milliseconds and used 4 cores, while Vanilla Go took 1.2 milliseconds and used 4 cores.

The results also show that key size has a much smaller impact when FIPS overhead is to be considered, but Nonce size sees much more degradation.

Impact of nonce length 256bit key

In terms of parallel processing, BoringSSL FIPS-enabled Go performed worse than Vanilla Go, especially when using 16 parallel goroutines. For instance, when using a key size of 128 bits and a nonce size of 16 bytes, BoringSSL FIPS-enabled Go took 35 milliseconds and used 15 cores, while Vanilla Go took 2.6 milliseconds and used 7 cores. At higher parallelism, CPU usage is almost 2x with BoringSSL, but that is restricted to 16 Byte long Nonce.

Impact on core usage with 12 byte nonce
Impact on CPU usage with 16 byte nonce

Encryption Performance in an End-to-End Workflow 

In an end-to-end (E2E) run, we evaluate the impact in a workflow, rather than just the isolated code. The workflow used was an application that is a data store, that ingests data in small chunks (<16MB) via APIs and writes it to disk post encryption.

The impact of the BoringSSL FIPS mode is not as significant as in isolated encryption code in terms of latency. The data shows that CPU usage is less when the FIPS mode is not used. However, the overall rate is not improved, as reducing the encryption times caused a load on storage and increased write latencies.

 

Encryption Latency

Write Latency

API Latency

Cores

Vanilla Go

13ms

30ms

45ms

6

BoringSSL 

28ms

19ms

48ms

10

Conclusion

In conclusion, the use of the BoringSSL FIPS mode in Go incurs overhead in terms of latency and CPU usage, especially when encryption is involved. The impact on overall performance varies based on workload characteristics. However, the use of the BoringSSL FIPS mode provides an extra layer of security, making it a trade-off between security and performance. Ultimately, the decision to use the BoringSSL FIPS mode or not will depend on the specific requirements and priorities of the system or application in question.

Next Steps

Learn more about the technical innovations and best practices powering cloud backup and data management on the Innovation Series section of Druva’s blog archive.