BoringSSL FIPS Mode in Go: Understanding the Overhead

Pankaj Pipada, Senior Technical Director

April 12, 2023

BoringSSL FIPS Mode in Go: Understanding the Overhead

Content

    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.

    Further Reading