FIPS-v1.jpg

This is a guest post written by Drew Varner. It originally appeared on the NineFX blog, and has been republished here with his permission. We hope you enjoy!.

NineFX, a HUBZone/SDVOSB-certified, value-added reseller for CircleCI, supports both commercial and federal government customers. The software that we ship to our federal customers must meet specific regulatory requirements from the National Institute of Standards & Technology (NIST). NIST’s Federal Information Processing Standard (FIPS) 140-2 is the standard that governs cryptographic modules in federal software.

Because we service both commercial and federal customers, in this post I will describe how we use CircleCI workflows to provide timely feedback on our software’s support of FIPS 140-2 cryptography, enabling us to monitor a project’s FIPS compatibility.

Current status

We are currently developing Shuttlebus, a TAXII/STIX 2 Cyber Threat Intelligence server targeting federal and commercial clients. For federal environments, Shuttlebus has to support Erlang’s crypto module with FIPS 140-2 enabled. For commercial environments, where FIPS 140-2 is not available, it has to support the module with FIPS 140-2 disabled. CircleCI’s workflow functionality allows us to evaluate Shuttlebus’ FIPS-mode compatibility on every GitHub push, concurrently with other steps in our build process.

CircleCI config

The following snippet from our .circleci/config.yml shows the three default configurations we use in our workflows, defined with YAML anchors (&).

defaults: &defaults
  working_directory: /home/circleci/shuttlebus
  docker:
    - image: elixir
      environment:
        MIX_ENV: test
test_defaults: &test_defaults
  working_directory: /home/circleci/shuttlebus
  docker:
    - image: elixir
      environment:
        MIX_ENV: test
    - image: circleci/postgres:10.1-alpine
      environment:
        POSTGRES_USER: someuser
        POSTGRES_PASSWORD: somepassword
        POSTGRES_DB: shuttlebus
fips_defaults: &fips_defaults
  working_directory: /home/circleci/shuttlebus_fips
  docker:
    - image: us.gcr.io/ninefx/elixir-fips
      environment:
        MIX_ENV: fips
    - image: circleci/postgres:10.1-alpine
      environment:
        POSTGRES_USER: user
        POSTGRES_PASSWORD: somepassword
        POSTGRES_DB: shuttlebus

We use the standard Elixir container compilation, static code analysis, and other jobs. For our FIPS-enabled cryptography job, we use our own custom Elixir Docker image built with a FIPS-enabled OpenSSL library. We host the image in a private registry on Google Container Registry (GCR). We build these images according to the OpenSSL FIPS 140-2 Security Policy. We run our FIPS build in a separate directory to avoid collisions with persisted data after attaching a workspace from an upstream container.

Our workflow executes the standard tasks of compilation, testing, and code coverage analysis. It includes multiple forms of static code checks including linting, success typing, format verification and cross-reference analysis. It also checks dependencies to see if updated versions are available in the package manager.

fips_workflows.png

fips

The fips task combines compilation and testing. We specify the FIPS defaults in the CircleCI config.yaml using YAML’s extend (<<) operator.

fips:
    <<: *fips_defaults
    steps:
      - checkout
      - run: mix local.hex --force
      - run: mix local.rebar --force
      - run:
          name: Deps
          command: mix deps.get
      - run:
          name: Migrate DB
          command: mix ecto.migrate -r ShuttlebusEcto.Repo
      - run:
          name: Seed DB
          command: mix run priv/repo/test_seeds.exs
      - run:
          name: FIPS Test
          command: mix test

Log output

During our fips job, we can verify that the underlying crypto module is operating in FIPS mode by examining captured log output in the CircleCI console:

mix test
15:44:56.272 [warn] FIPS mode :enabled
15:44:56.282 [info] starting shuttlebus with options [port: 8443, certfile: "/home/circleci/shuttlebus_fips/_build/fips/lib/shuttlebus/priv/cert.pem", keyfile: "/home/circleci/shuttlebus_fips/_build/fips/lib/shuttlebus/priv/key.pem", connections: 1000]
15:44:56.317 [info] Serving securely using HTTP/1 and HTTP/2 on port 8443
...

It’s clear from the output in our normal test job that FIPS is not enabled when running on a container where OpenSSL is not compiled with FIPS support:

15:44:02.201 [warn] FIPS mode :not_supported
15:44:02.214 [info] starting shuttlebus with options [port: 8443, certfile: "/home/circleci/shuttlebus/_build/test/lib/shuttlebus/priv/cert.pem", keyfile: "/home/circleci/shuttlebus/_build/test/lib/shuttlebus/priv/key.pem", connections: 1000]
15:44:02.259 [info] Serving securely using HTTP/1 and HTTP/2 on port 8443
...

For more information about how we created our custom container, we provide examples of how to configure OpenSSL, Erlang, and Elixir for FIPS 140-2 operation in Docker Hub. They are an excellent introduction to configuring your containers with OpenSSL in FIPS mode. These can be used by those who wish to check for FIPS 140-2 compatibility, however, the images built by our Docker Hub examples are not FIPS 140-2 compliant because they are not built according to the Security Officer instructions for OpenSSL, which specifies:

Any deviation from specified verification, protection, installation and initialization procedures will result in a non-FIPS 140-2 compliant module.

Summary

Automating FIPS testing as a workflow job means it can run concurrently with other build tasks. This concurrency provides faster feedback to developers on their code changes. It provides developers with confidence that their changes will work if FIPS or non-FIPS cryptography is used. The best part is that it provides assurances throughout the development process, as opposed to manual compliance checks just before a product or patch release.

NineFX is a HUBZone/SDVOSB-certified, value-added reseller for CircleCI. If you would like CircleCI consulting specific to US Federal markets or FIPS 140-2, contact us.


A software developer with over 15 years of experience, Drew Varner founded NineFX, a HUBZone/SDVOSB firm delivering innovative software solutions to commercial and Federal customers. He’s a veteran of the US Army and addicted to functional programming.