GoSuda

Structuur van de FIPS 140-2- en FIPS 140-3-implementaties in de standaard cryptografiebibliotheek van Go

By Gosunuts views ...

FIPS 140 (Federal Information Processing Standard Publication 140)

FIPS 140 is een door het Amerikaanse NIST vastgestelde standaard voor de beveiligingscertificering van cryptografische modules. Deze standaard beoordeelt of een specifieke cryptografische module of bibliotheek voldoet aan de beveiligingseisen die door het NIST zijn gedefinieerd. Daarom betekent het doorstaan van de FIPS 140-certificering dat de betreffende module officieel als betrouwbaar beveiligd is aangemerkt, en dat zij kan worden gebruikt in sectoren waar beveiliging van groot belang is, zoals de financiële sector, de gezondheidszorg en defensie.

Sinds de eerste vaststelling van FIPS 140 in 1994 is de standaard in 2001 herzien tot FIPS 140-2 en in 2019 tot FIPS 140-3. Tot op heden vereisen veel systemen en toepassingen nog steeds certificering volgens FIPS 140-2 of FIPS 140-3.

FIPS 140 en programmeertalen

Om deze reden wordt een cryptografische module die is gecertificeerd volgens FIPS 140 in verschillende programmeertalen en omgevingen als een de facto standaard gebruikt. Te noemen zijn onder meer OpenSSL, BoringSSL, LibreSSL en NSS, die in beveiligingsgevoelige toepassingen het meest breed worden ingezet.

De meeste FIPS 140-gecertificeerde modules zijn geschreven in C of C++. Daarom wordt in talen als PHP, Python en JavaScript de FIPS-omgeving doorgaans niet door deze modules rechtstreeks te gebruiken opgebouwd, maar door ze via een externe Provider-module te koppelen. Deze aanpak kent echter enkele beperkingen.

  • Versieconflicten

    FIPS 140-certificering wordt uitsluitend verleend voor een specifieke versie. Om een nieuwere versie van de module te gebruiken, moet daarom opnieuw een certificeringsprocedure worden doorlopen, waarbij een versieverschil tussen de module die de applicatie gebruikt en de FIPS-gecertificeerde module kan ontstaan. Indien een niet-goedgekeurde versie wordt gebruikt, wordt de omgeving niet langer als FIPS-gecertificeerde omgeving beschouwd.

  • Dynamisch laden en prestatieverlies

    De meeste talen laden FIPS 140-gecertificeerde modules als dynamische bibliotheek. Deze werkwijze kan tijdens initialisatie en uitvoering leiden tot prestatieverlies, en wanneer zich tijdens de runtime een probleem voordoet, bestaat het risico dat de stabiliteit van de gehele applicatie rechtstreeks wordt aangetast.

  • Beveiligingskwetsbaarheden

    Zoals hierboven is opgemerkt, bestaat er bij structuren waarin externe modules worden gekoppeld, zoals de OpenSSL Provider, het risico dat kwetsbaarheden in die module rechtstreeks doorwerken in de applicatie. Bovendien vormt de communicatielaag tussen de applicatie en de externe module zelf een extra aanvalsoppervlak, waarvoor een afzonderlijke beveiligingslaag noodzakelijk wordt. Dit vergroot de complexiteit en kan leiden tot onvoorziene kwetsbaarheden.

FIPS 140 en Golang

Om deze reden heeft Golang een andere strategie gekozen. Go is FIPS 140-certificering niet afhankelijk van externe hulpmiddelen gaan maken, maar heeft gekozen voor ondersteuning die rechtstreeks in de officiële cryptografische bibliotheek is opgenomen. Ontwikkelaars hoeven daardoor geen afzonderlijke Provider te installeren of te configureren, maar kunnen het standaardpakket crypto ongewijzigd gebruiken en hoeven alleen de FIPS-certificeringsmodus (GOFIPS=1) in te schakelen. Doordat hierbij de communicatiegrens met externe modules is verwijderd, wordt de beveiliging versterkt, en omdat alleen een statisch gecompileerd enkelvoudig binair bestand hoeft te worden gedistribueerd, wordt ook het beheer vereenvoudigd.

FIPS 140-2 en Golang

Hiertoe heeft Golang de BoringCrypto-module, afgeleid van BoringSSL, in de Go-runtime opgenomen en daarmee FIPS 140-2-certificering verkregen. BoringCrypto kan vanaf Go 1.19 op bepaalde distributies worden geactiveerd, waardoor Go-toepassingen zonder afzonderlijke externe modules een FIPS 140-2-gecertificeerde omgeving kunnen opzetten.

BoringCrypto is echter gebaseerd op OpenSSL en is daarom nog steeds afhankelijk van C. Go-toepassingen worden daardoor niet volledig als zelfstandig binair bestand gebouwd, en er bestond de beperking dat de benodigde C-bibliotheken samen met de applicatie moesten worden gedistribueerd.

FIPS 140-3 en Golang

Het Go-team heeft, om deze beperkingen te overwinnen, de bestaande standaard cryptografische bibliotheek van Go verbeterd zodat zij aan de FIPS 140-3-specificatie voldoet. Deze verbeterde module wordt sinds Go 1.21 experimenteel aangeboden, en de certificeringsbeoordeling door het NIST voor FIPS 140-3 is momenteel gaande.Lijst van NIST-modules in FIPS 140-3-beoordeling

Dit toont de volwassenheid van de cryptografische bibliotheek van Go aan, en hiermee kan Go een FIPS 140-3-gecertificeerde omgeving bieden in de vorm van een volledig zelfstandig enkelvoudig binair bestand.

Daarnaast heeft het Go-team zich er niet toe beperkt alleen aan de FIPS 140-3-standaard te voldoen, maar heeft het de beveiliging ook zelfstandig versterkt.

  • Fail Fast

    De FIPS-modus van Go past een Fail Fast-beveiligingsmodel toe: wanneer een niet-gecertificeerd algoritme wordt aangeroepen, wordt de uitvoering onmiddellijk afgebroken met een panic. Dit biedt, in tegenstelling tot Provider-gebaseerde modellen in andere talen, die een fallback-mogelijkheid openlaten, een strengere en duidelijkere waarborg op het gebied van beveiliging en regelgevingsnaleving.

  • Hedged Signature

    De FIPS 140-3-standaard beveelt bij ECDSA-handtekeningen de RFC6979-methode aan. Go heeft daarnaast een Hedged-methode geïntroduceerd, waarmee het krachtiger reageert op zijdelingse kanaalaanvallen (side-channel attacks) die tijdens het ondertekenen kunnen optreden.

  • Versterkte willekeurige-getallengenerator

    De willekeurige-getallengenerator van Go maakt gebruik van een DRBG (Deterministic Random Bit Generator) in de gebruikersruimte, maar injecteert daarnaast entropie van de besturingssysteemkernel, waardoor hoogwaardige willekeurige getallen worden gegenereerd, zowel in de gebruikersruimte als in de kernelruimte. Hiermee wordt de beveiliging van de willekeurige-getallengenerator verder versterkt.