diff mbox

vnc: disable VNC password authentication (security type 2) when in FIPS mode

Message ID 20120501212040.27850.27184.stgit@sifl
State New
Headers show

Commit Message

Paul Moore May 1, 2012, 9:20 p.m. UTC
FIPS 140-2 requires disabling certain ciphers, including DES, which is used
by VNC to obscure passwords when they are sent over the network.  The
solution for FIPS users is to disable the use of VNC password auth when the
host system is operating in FIPS mode.

This patch causes qemu to emits a syslog entry indicating that VNC password
auth is disabled when it detects the host is running in FIPS mode, and
unless a VNC password was specified on the command line it continues
normally.  However, if a VNC password was given on the command line, qemu
fails with an error message to stderr explaining that that VNC password
auth is not allowed in FIPS mode.

Signed-off-by: Paul Moore <pmoore@redhat.com>
---
 qemu-doc.texi |    8 +++++---
 ui/vnc.c      |   32 ++++++++++++++++++++++++++++++++
 ui/vnc.h      |    1 +
 3 files changed, 38 insertions(+), 3 deletions(-)

Comments

Andreas Färber May 1, 2012, 10:54 p.m. UTC | #1
Am 01.05.2012 23:20, schrieb Paul Moore:
> FIPS 140-2 requires disabling certain ciphers, including DES, which is used
> by VNC to obscure passwords when they are sent over the network.  The
> solution for FIPS users is to disable the use of VNC password auth when the
> host system is operating in FIPS mode.
> 
> This patch causes qemu to emits a syslog entry indicating that VNC password

"to emit"

> auth is disabled when it detects the host is running in FIPS mode, and
> unless a VNC password was specified on the command line it continues
> normally.  However, if a VNC password was given on the command line, qemu
> fails with an error message to stderr explaining that that VNC password

"explaining that VNC"

> auth is not allowed in FIPS mode.
> 
> Signed-off-by: Paul Moore <pmoore@redhat.com>

Interesting feature. :)

> diff --git a/ui/vnc.c b/ui/vnc.c
> index deb9ecd..620791e 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -32,6 +32,7 @@
>  #include "acl.h"
>  #include "qemu-objects.h"
>  #include "qmp-commands.h"
> +#include <syslog.h>

syslog.h is POSIX, but it'll need a guard for mingw32.

> @@ -48,6 +49,24 @@ static DisplayChangeListener *dcl;
>  static int vnc_cursor_define(VncState *vs);
>  static void vnc_release_modifiers(VncState *vs);
>  
> +static int fips_enabled(void)
> +{
> +    int enabled = 0;
> +    char value;
> +    FILE *fds;
> +
> +    fds = fopen("/proc/sys/crypto/fips_enabled", "r");

How standardized is this? Should we limit this to __linux__ or something?

> +    if (fds == NULL) {
> +        return 0;
> +    }
> +    if (fread(&value, sizeof(value), 1, fds) == 1 && value == '1') {
> +        enabled = 1;
> +    }
> +    fclose(fds);
> +
> +    return enabled;
> +}

bool would seem nicer as return type and field type below.

Andreas

> +
>  static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
>  {
>  #ifdef _VNC_DEBUG

> diff --git a/ui/vnc.h b/ui/vnc.h
> index a851ebd..8746a98 100644
> --- a/ui/vnc.h
> +++ b/ui/vnc.h
> @@ -160,6 +160,7 @@ struct VncDisplay
>      char *display;
>      char *password;
>      time_t expires;
> +    int fips;
>      int auth;
>      bool lossy;
>      bool non_adaptive;
Anthony Liguori May 1, 2012, 11:26 p.m. UTC | #2
On 05/01/2012 04:20 PM, Paul Moore wrote:
> FIPS 140-2 requires disabling certain ciphers, including DES, which is used
> by VNC to obscure passwords when they are sent over the network.  The
> solution for FIPS users is to disable the use of VNC password auth when the
> host system is operating in FIPS mode.

Sorry, what?

Does FIPS really require software to detect when FIPS is enabled and actively 
disable features???  That's absurd.

Can you point to another software package that does something like this?

Regards,

Anthony Liguori

>
> This patch causes qemu to emits a syslog entry indicating that VNC password
> auth is disabled when it detects the host is running in FIPS mode, and
> unless a VNC password was specified on the command line it continues
> normally.  However, if a VNC password was given on the command line, qemu
> fails with an error message to stderr explaining that that VNC password
> auth is not allowed in FIPS mode.
>
> Signed-off-by: Paul Moore<pmoore@redhat.com>
> ---
>   qemu-doc.texi |    8 +++++---
>   ui/vnc.c      |   32 ++++++++++++++++++++++++++++++++
>   ui/vnc.h      |    1 +
>   3 files changed, 38 insertions(+), 3 deletions(-)
>
> diff --git a/qemu-doc.texi b/qemu-doc.texi
> index e5d7ac4..f9b113e 100644
> --- a/qemu-doc.texi
> +++ b/qemu-doc.texi
> @@ -1124,9 +1124,11 @@ the protocol limits passwords to 8 characters it should not be considered
>   to provide high security. The password can be fairly easily brute-forced by
>   a client making repeat connections. For this reason, a VNC server using password
>   authentication should be restricted to only listen on the loopback interface
> -or UNIX domain sockets. Password authentication is requested with the @code{password}
> -option, and then once QEMU is running the password is set with the monitor. Until
> -the monitor is used to set the password all clients will be rejected.
> +or UNIX domain sockets. Password authentication is not supported when operating
> +in FIPS 140-2 compliance mode as it requires the use of the DES cipher. Password
> +authentication is requested with the @code{password} option, and then once QEMU
> +is running the password is set with the monitor. Until the monitor is used to
> +set the password all clients will be rejected.
>
>   @example
>   qemu [...OPTIONS...] -vnc :1,password -monitor stdio
> diff --git a/ui/vnc.c b/ui/vnc.c
> index deb9ecd..620791e 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -32,6 +32,7 @@
>   #include "acl.h"
>   #include "qemu-objects.h"
>   #include "qmp-commands.h"
> +#include<syslog.h>
>
>   #define VNC_REFRESH_INTERVAL_BASE 30
>   #define VNC_REFRESH_INTERVAL_INC  50
> @@ -48,6 +49,24 @@ static DisplayChangeListener *dcl;
>   static int vnc_cursor_define(VncState *vs);
>   static void vnc_release_modifiers(VncState *vs);
>
> +static int fips_enabled(void)
> +{
> +    int enabled = 0;
> +    char value;
> +    FILE *fds;
> +
> +    fds = fopen("/proc/sys/crypto/fips_enabled", "r");
> +    if (fds == NULL) {
> +        return 0;
> +    }
> +    if (fread(&value, sizeof(value), 1, fds) == 1&&  value == '1') {
> +        enabled = 1;
> +    }
> +    fclose(fds);
> +
> +    return enabled;
> +}
> +
>   static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
>   {
>   #ifdef _VNC_DEBUG
> @@ -2748,6 +2767,12 @@ void vnc_display_init(DisplayState *ds)
>       dcl->idle = 1;
>       vnc_display = vs;
>
> +    vs->fips = fips_enabled();
> +    VNC_DEBUG("FIPS mode %s\n", (vs->fips ? "enabled" : "disabled"));
> +    if (vs->fips) {
> +        syslog(LOG_NOTICE, "Disabling VNC password auth due to FIPS mode\n");
> +    }
> +
>       vs->lsock = -1;
>
>       vs->ds = ds;
> @@ -2892,6 +2917,13 @@ int vnc_display_open(DisplayState *ds, const char *display)
>       while ((options = strchr(options, ','))) {
>           options++;
>           if (strncmp(options, "password", 8) == 0) {
> +            if (vs->fips) {
> +                fprintf(stderr,
> +                        "VNC password auth disabled due to FIPS mode\n");
> +                g_free(vs->display);
> +                vs->display = NULL;
> +                return -1;
> +            }
>               password = 1; /* Require password auth */
>           } else if (strncmp(options, "reverse", 7) == 0) {
>               reverse = 1;
> diff --git a/ui/vnc.h b/ui/vnc.h
> index a851ebd..8746a98 100644
> --- a/ui/vnc.h
> +++ b/ui/vnc.h
> @@ -160,6 +160,7 @@ struct VncDisplay
>       char *display;
>       char *password;
>       time_t expires;
> +    int fips;
>       int auth;
>       bool lossy;
>       bool non_adaptive;
>
>
>
George Wilson May 1, 2012, 11:43 p.m. UTC | #3
Anthony Liguori <anthony@codemonkey.ws> wrote on 05/01/2012 06:26:05 PM:

> Anthony Liguori <anthony@codemonkey.ws>
> 05/01/2012 06:26 PM
>
> To
>
> Paul Moore <pmoore@redhat.com>
>
> cc
>
> qemu-devel@nongnu.org, George Wilson/Austin/IBM@IBMUS
>
> Subject
>
> Re: [Qemu-devel] [PATCH] vnc: disable VNC password authentication
> (security type 2) when in FIPS mode
>
> On 05/01/2012 04:20 PM, Paul Moore wrote:
> > FIPS 140-2 requires disabling certain ciphers, including DES, which is
used
> > by VNC to obscure passwords when they are sent over the network.  The
> > solution for FIPS users is to disable the use of VNC password auth when
the
> > host system is operating in FIPS mode.
>
> Sorry, what?
>
> Does FIPS really require software to detect when FIPS is enabled
andactively
> disable features???  That's absurd.
>
> Can you point to another software package that does something like this?

Yes, it's true that only FIPS-approved algorithms are permitted for use in
FIPS
mode.  The kernel and all other FIPS 140-2 validated crypto modules like
OpenSSL
and NSS are required to restrict algorithms to the approved set.  The
kernel
sets /proc/sys/crypto/fips_enabled so that programs can detect FIPS mode
and
behave in accordance with the standard.

>
> Regards,
>
> Anthony Liguori
>
> >
> > This patch causes qemu to emits a syslog entry indicating that VNC
password
> > auth is disabled when it detects the host is running in FIPS mode, and
> > unless a VNC password was specified on the command line it continues
> > normally.  However, if a VNC password was given on the command line,
qemu
> > fails with an error message to stderr explaining that that VNC password
> > auth is not allowed in FIPS mode.
> >
> > Signed-off-by: Paul Moore<pmoore@redhat.com>
> > ---
> >   qemu-doc.texi |    8 +++++---
> >   ui/vnc.c      |   32 ++++++++++++++++++++++++++++++++
> >   ui/vnc.h      |    1 +
> >   3 files changed, 38 insertions(+), 3 deletions(-)
> >
> > diff --git a/qemu-doc.texi b/qemu-doc.texi
> > index e5d7ac4..f9b113e 100644
> > --- a/qemu-doc.texi
> > +++ b/qemu-doc.texi
> > @@ -1124,9 +1124,11 @@ the protocol limits passwords to 8
> characters it should not be considered
> >   to provide high security. The password can be fairly easily
> brute-forced by
> >   a client making repeat connections. For this reason, a VNC
> server using password
> >   authentication should be restricted to only listen on the
> loopback interface
> > -or UNIX domain sockets. Password authentication is requested with
> the @code{password}
> > -option, and then once QEMU is running the password is set with
> the monitor. Until
> > -the monitor is used to set the password all clients will be rejected.
> > +or UNIX domain sockets. Password authentication is not supported
> when operating
> > +in FIPS 140-2 compliance mode as it requires the use of the DES
> cipher. Password
> > +authentication is requested with the @code{password} option, and
> then once QEMU
> > +is running the password is set with the monitor. Until the
> monitor is used to
> > +set the password all clients will be rejected.
> >
> >   @example
> >   qemu [...OPTIONS...] -vnc :1,password -monitor stdio
> > diff --git a/ui/vnc.c b/ui/vnc.c
> > index deb9ecd..620791e 100644
> > --- a/ui/vnc.c
> > +++ b/ui/vnc.c
> > @@ -32,6 +32,7 @@
> >   #include "acl.h"
> >   #include "qemu-objects.h"
> >   #include "qmp-commands.h"
> > +#include<syslog.h>
> >
> >   #define VNC_REFRESH_INTERVAL_BASE 30
> >   #define VNC_REFRESH_INTERVAL_INC  50
> > @@ -48,6 +49,24 @@ static DisplayChangeListener *dcl;
> >   static int vnc_cursor_define(VncState *vs);
> >   static void vnc_release_modifiers(VncState *vs);
> >
> > +static int fips_enabled(void)
> > +{
> > +    int enabled = 0;
> > +    char value;
> > +    FILE *fds;
> > +
> > +    fds = fopen("/proc/sys/crypto/fips_enabled", "r");
> > +    if (fds == NULL) {
> > +        return 0;
> > +    }
> > +    if (fread(&value, sizeof(value), 1, fds) == 1&&  value == '1') {
> > +        enabled = 1;
> > +    }
> > +    fclose(fds);
> > +
> > +    return enabled;
> > +}
> > +
> >   static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
> >   {
> >   #ifdef _VNC_DEBUG
> > @@ -2748,6 +2767,12 @@ void vnc_display_init(DisplayState *ds)
> >       dcl->idle = 1;
> >       vnc_display = vs;
> >
> > +    vs->fips = fips_enabled();
> > +    VNC_DEBUG("FIPS mode %s\n", (vs->fips ? "enabled" : "disabled"));
> > +    if (vs->fips) {
> > +        syslog(LOG_NOTICE, "Disabling VNC password auth due to
> FIPS mode\n");
> > +    }
> > +
> >       vs->lsock = -1;
> >
> >       vs->ds = ds;
> > @@ -2892,6 +2917,13 @@ int vnc_display_open(DisplayState *ds,
> const char *display)
> >       while ((options = strchr(options, ','))) {
> >           options++;
> >           if (strncmp(options, "password", 8) == 0) {
> > +            if (vs->fips) {
> > +                fprintf(stderr,
> > +                        "VNC password auth disabled due to FIPS mode
\n");
> > +                g_free(vs->display);
> > +                vs->display = NULL;
> > +                return -1;
> > +            }
> >               password = 1; /* Require password auth */
> >           } else if (strncmp(options, "reverse", 7) == 0) {
> >               reverse = 1;
> > diff --git a/ui/vnc.h b/ui/vnc.h
> > index a851ebd..8746a98 100644
> > --- a/ui/vnc.h
> > +++ b/ui/vnc.h
> > @@ -160,6 +160,7 @@ struct VncDisplay
> >       char *display;
> >       char *password;
> >       time_t expires;
> > +    int fips;
> >       int auth;
> >       bool lossy;
> >       bool non_adaptive;
> >
> >
> >
>

Regards,
George Wilson
Anthony Liguori May 1, 2012, 11:45 p.m. UTC | #4
On 05/01/2012 06:43 PM, George Wilson wrote:
>
> Anthony Liguori<anthony@codemonkey.ws>  wrote on 05/01/2012 06:26:05 PM:
>
>> Anthony Liguori<anthony@codemonkey.ws>
>> 05/01/2012 06:26 PM
>>
>> To
>>
>> Paul Moore<pmoore@redhat.com>
>>
>> cc
>>
>> qemu-devel@nongnu.org, George Wilson/Austin/IBM@IBMUS
>>
>> Subject
>>
>> Re: [Qemu-devel] [PATCH] vnc: disable VNC password authentication
>> (security type 2) when in FIPS mode
>>
>> On 05/01/2012 04:20 PM, Paul Moore wrote:
>>> FIPS 140-2 requires disabling certain ciphers, including DES, which is
> used
>>> by VNC to obscure passwords when they are sent over the network.  The
>>> solution for FIPS users is to disable the use of VNC password auth when
> the
>>> host system is operating in FIPS mode.
>>
>> Sorry, what?
>>
>> Does FIPS really require software to detect when FIPS is enabled
> andactively
>> disable features???  That's absurd.
>>
>> Can you point to another software package that does something like this?
>
> Yes, it's true that only FIPS-approved algorithms are permitted for use in
> FIPS
> mode.  The kernel and all other FIPS 140-2 validated crypto modules like
> OpenSSL
> and NSS are required to restrict algorithms to the approved set.  The
> kernel
> sets /proc/sys/crypto/fips_enabled so that programs can detect FIPS mode
> and
> behave in accordance with the standard.

But this is nonsensical. It would allow no-password to be configured for the VNC 
server but not DES?  Why is that okay?  It's not like we enable DES passwords by 
default.  A user has to explicitly configure it.

Is there an open source app that actually keys off of fips_enabled?

Regards,

Anthony Liguori

>
>>
>> Regards,
>>
>> Anthony Liguori
>>
>>>
>>> This patch causes qemu to emits a syslog entry indicating that VNC
> password
>>> auth is disabled when it detects the host is running in FIPS mode, and
>>> unless a VNC password was specified on the command line it continues
>>> normally.  However, if a VNC password was given on the command line,
> qemu
>>> fails with an error message to stderr explaining that that VNC password
>>> auth is not allowed in FIPS mode.
>>>
>>> Signed-off-by: Paul Moore<pmoore@redhat.com>
>>> ---
>>>    qemu-doc.texi |    8 +++++---
>>>    ui/vnc.c      |   32 ++++++++++++++++++++++++++++++++
>>>    ui/vnc.h      |    1 +
>>>    3 files changed, 38 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/qemu-doc.texi b/qemu-doc.texi
>>> index e5d7ac4..f9b113e 100644
>>> --- a/qemu-doc.texi
>>> +++ b/qemu-doc.texi
>>> @@ -1124,9 +1124,11 @@ the protocol limits passwords to 8
>> characters it should not be considered
>>>    to provide high security. The password can be fairly easily
>> brute-forced by
>>>    a client making repeat connections. For this reason, a VNC
>> server using password
>>>    authentication should be restricted to only listen on the
>> loopback interface
>>> -or UNIX domain sockets. Password authentication is requested with
>> the @code{password}
>>> -option, and then once QEMU is running the password is set with
>> the monitor. Until
>>> -the monitor is used to set the password all clients will be rejected.
>>> +or UNIX domain sockets. Password authentication is not supported
>> when operating
>>> +in FIPS 140-2 compliance mode as it requires the use of the DES
>> cipher. Password
>>> +authentication is requested with the @code{password} option, and
>> then once QEMU
>>> +is running the password is set with the monitor. Until the
>> monitor is used to
>>> +set the password all clients will be rejected.
>>>
>>>    @example
>>>    qemu [...OPTIONS...] -vnc :1,password -monitor stdio
>>> diff --git a/ui/vnc.c b/ui/vnc.c
>>> index deb9ecd..620791e 100644
>>> --- a/ui/vnc.c
>>> +++ b/ui/vnc.c
>>> @@ -32,6 +32,7 @@
>>>    #include "acl.h"
>>>    #include "qemu-objects.h"
>>>    #include "qmp-commands.h"
>>> +#include<syslog.h>
>>>
>>>    #define VNC_REFRESH_INTERVAL_BASE 30
>>>    #define VNC_REFRESH_INTERVAL_INC  50
>>> @@ -48,6 +49,24 @@ static DisplayChangeListener *dcl;
>>>    static int vnc_cursor_define(VncState *vs);
>>>    static void vnc_release_modifiers(VncState *vs);
>>>
>>> +static int fips_enabled(void)
>>> +{
>>> +    int enabled = 0;
>>> +    char value;
>>> +    FILE *fds;
>>> +
>>> +    fds = fopen("/proc/sys/crypto/fips_enabled", "r");
>>> +    if (fds == NULL) {
>>> +        return 0;
>>> +    }
>>> +    if (fread(&value, sizeof(value), 1, fds) == 1&&   value == '1') {
>>> +        enabled = 1;
>>> +    }
>>> +    fclose(fds);
>>> +
>>> +    return enabled;
>>> +}
>>> +
>>>    static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
>>>    {
>>>    #ifdef _VNC_DEBUG
>>> @@ -2748,6 +2767,12 @@ void vnc_display_init(DisplayState *ds)
>>>        dcl->idle = 1;
>>>        vnc_display = vs;
>>>
>>> +    vs->fips = fips_enabled();
>>> +    VNC_DEBUG("FIPS mode %s\n", (vs->fips ? "enabled" : "disabled"));
>>> +    if (vs->fips) {
>>> +        syslog(LOG_NOTICE, "Disabling VNC password auth due to
>> FIPS mode\n");
>>> +    }
>>> +
>>>        vs->lsock = -1;
>>>
>>>        vs->ds = ds;
>>> @@ -2892,6 +2917,13 @@ int vnc_display_open(DisplayState *ds,
>> const char *display)
>>>        while ((options = strchr(options, ','))) {
>>>            options++;
>>>            if (strncmp(options, "password", 8) == 0) {
>>> +            if (vs->fips) {
>>> +                fprintf(stderr,
>>> +                        "VNC password auth disabled due to FIPS mode
> \n");
>>> +                g_free(vs->display);
>>> +                vs->display = NULL;
>>> +                return -1;
>>> +            }
>>>                password = 1; /* Require password auth */
>>>            } else if (strncmp(options, "reverse", 7) == 0) {
>>>                reverse = 1;
>>> diff --git a/ui/vnc.h b/ui/vnc.h
>>> index a851ebd..8746a98 100644
>>> --- a/ui/vnc.h
>>> +++ b/ui/vnc.h
>>> @@ -160,6 +160,7 @@ struct VncDisplay
>>>        char *display;
>>>        char *password;
>>>        time_t expires;
>>> +    int fips;
>>>        int auth;
>>>        bool lossy;
>>>        bool non_adaptive;
>>>
>>>
>>>
>>
>
> Regards,
> George Wilson
George Wilson May 2, 2012, 12:17 a.m. UTC | #5
Anthony Liguori <anthony@codemonkey.ws> wrote on 05/01/2012 06:45:47 PM:

> Anthony Liguori <anthony@codemonkey.ws>
> 05/01/2012 06:45 PM
>
> To
>
> George Wilson/Austin/IBM@IBMUS
>
> cc
>
> Paul Moore <pmoore@redhat.com>, qemu-devel@nongnu.org
>
> Subject
>
> Re: [Qemu-devel] [PATCH] vnc: disable VNC password authentication
> (security type 2) when in FIPS mode
>
> On 05/01/2012 06:43 PM, George Wilson wrote:
> >
> > Anthony Liguori<anthony@codemonkey.ws>  wrote on 05/01/2012 06:26:05
PM:
> >
> >> Anthony Liguori<anthony@codemonkey.ws>
> >> 05/01/2012 06:26 PM
> >>
> >> To
> >>
> >> Paul Moore<pmoore@redhat.com>
> >>
> >> cc
> >>
> >> qemu-devel@nongnu.org, George Wilson/Austin/IBM@IBMUS
> >>
> >> Subject
> >>
> >> Re: [Qemu-devel] [PATCH] vnc: disable VNC password authentication
> >> (security type 2) when in FIPS mode
> >>
> >> On 05/01/2012 04:20 PM, Paul Moore wrote:
> >>> FIPS 140-2 requires disabling certain ciphers, including DES, which
is
> > used
> >>> by VNC to obscure passwords when they are sent over the network.  The
> >>> solution for FIPS users is to disable the use of VNC password auth
when
> > the
> >>> host system is operating in FIPS mode.
> >>
> >> Sorry, what?
> >>
> >> Does FIPS really require software to detect when FIPS is enabled
> > andactively
> >> disable features???  That's absurd.
> >>
> >> Can you point to another software package that does something like
this?
> >
> > Yes, it's true that only FIPS-approved algorithms are permitted for use
in
> > FIPS
> > mode.  The kernel and all other FIPS 140-2 validated crypto modules
like
> > OpenSSL
> > and NSS are required to restrict algorithms to the approved set.  The
> > kernel
> > sets /proc/sys/crypto/fips_enabled so that programs can detect FIPS
mode
> > and
> > behave in accordance with the standard.
>
> But this is nonsensical. It would allow no-password to be configured
> for the VNC
> server but not DES?  Why is that okay?  It's not like we enable DES
> passwords by
> default.  A user has to explicitly configure it.

Because the standard says so :-)  If you're going to encrypt and need to
be FIPS 140-2 compliant, choose a FIPS-approved algorithm like AES.  And
adhere to approved key sizes and modes.  And make sure the algorithm does
self tests.  And so on.  It's best call into a FIPS-compliant library.
If the passwords are sent over an untrusted network, it's not OK not to
encrypt them from a security POV.

>
> Is there an open source app that actually keys off of fips_enabled?

libgcrypt is one example:

$strings /lib64/libgcrypt.so.11.5.3 | grep fips_enabled
/etc/gcrypt/fips_enabled
/proc/sys/crypto/fips_enabled

info libgcrypt has some details on FIPS mode.

>
> Regards,
>
> Anthony Liguori
>
> >
> >>
> >> Regards,
> >>
> >> Anthony Liguori
> >>
> >>>
> >>> This patch causes qemu to emits a syslog entry indicating that VNC
> > password
> >>> auth is disabled when it detects the host is running in FIPS mode,
and
> >>> unless a VNC password was specified on the command line it continues
> >>> normally.  However, if a VNC password was given on the command line,
> > qemu
> >>> fails with an error message to stderr explaining that that VNC
password
> >>> auth is not allowed in FIPS mode.
> >>>
> >>> Signed-off-by: Paul Moore<pmoore@redhat.com>
> >>> ---
> >>>    qemu-doc.texi |    8 +++++---
> >>>    ui/vnc.c      |   32 ++++++++++++++++++++++++++++++++
> >>>    ui/vnc.h      |    1 +
> >>>    3 files changed, 38 insertions(+), 3 deletions(-)
> >>>
> >>> diff --git a/qemu-doc.texi b/qemu-doc.texi
> >>> index e5d7ac4..f9b113e 100644
> >>> --- a/qemu-doc.texi
> >>> +++ b/qemu-doc.texi
> >>> @@ -1124,9 +1124,11 @@ the protocol limits passwords to 8
> >> characters it should not be considered
> >>>    to provide high security. The password can be fairly easily
> >> brute-forced by
> >>>    a client making repeat connections. For this reason, a VNC
> >> server using password
> >>>    authentication should be restricted to only listen on the
> >> loopback interface
> >>> -or UNIX domain sockets. Password authentication is requested with
> >> the @code{password}
> >>> -option, and then once QEMU is running the password is set with
> >> the monitor. Until
> >>> -the monitor is used to set the password all clients will be
rejected.
> >>> +or UNIX domain sockets. Password authentication is not supported
> >> when operating
> >>> +in FIPS 140-2 compliance mode as it requires the use of the DES
> >> cipher. Password
> >>> +authentication is requested with the @code{password} option, and
> >> then once QEMU
> >>> +is running the password is set with the monitor. Until the
> >> monitor is used to
> >>> +set the password all clients will be rejected.
> >>>
> >>>    @example
> >>>    qemu [...OPTIONS...] -vnc :1,password -monitor stdio
> >>> diff --git a/ui/vnc.c b/ui/vnc.c
> >>> index deb9ecd..620791e 100644
> >>> --- a/ui/vnc.c
> >>> +++ b/ui/vnc.c
> >>> @@ -32,6 +32,7 @@
> >>>    #include "acl.h"
> >>>    #include "qemu-objects.h"
> >>>    #include "qmp-commands.h"
> >>> +#include<syslog.h>
> >>>
> >>>    #define VNC_REFRESH_INTERVAL_BASE 30
> >>>    #define VNC_REFRESH_INTERVAL_INC  50
> >>> @@ -48,6 +49,24 @@ static DisplayChangeListener *dcl;
> >>>    static int vnc_cursor_define(VncState *vs);
> >>>    static void vnc_release_modifiers(VncState *vs);
> >>>
> >>> +static int fips_enabled(void)
> >>> +{
> >>> +    int enabled = 0;
> >>> +    char value;
> >>> +    FILE *fds;
> >>> +
> >>> +    fds = fopen("/proc/sys/crypto/fips_enabled", "r");
> >>> +    if (fds == NULL) {
> >>> +        return 0;
> >>> +    }
> >>> +    if (fread(&value, sizeof(value), 1, fds) == 1&&   value == '1')
{
> >>> +        enabled = 1;
> >>> +    }
> >>> +    fclose(fds);
> >>> +
> >>> +    return enabled;
> >>> +}
> >>> +
> >>>    static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
> >>>    {
> >>>    #ifdef _VNC_DEBUG
> >>> @@ -2748,6 +2767,12 @@ void vnc_display_init(DisplayState *ds)
> >>>        dcl->idle = 1;
> >>>        vnc_display = vs;
> >>>
> >>> +    vs->fips = fips_enabled();
> >>> +    VNC_DEBUG("FIPS mode %s\n", (vs->fips ? "enabled" :
"disabled"));
> >>> +    if (vs->fips) {
> >>> +        syslog(LOG_NOTICE, "Disabling VNC password auth due to
> >> FIPS mode\n");
> >>> +    }
> >>> +
> >>>        vs->lsock = -1;
> >>>
> >>>        vs->ds = ds;
> >>> @@ -2892,6 +2917,13 @@ int vnc_display_open(DisplayState *ds,
> >> const char *display)
> >>>        while ((options = strchr(options, ','))) {
> >>>            options++;
> >>>            if (strncmp(options, "password", 8) == 0) {
> >>> +            if (vs->fips) {
> >>> +                fprintf(stderr,
> >>> +                        "VNC password auth disabled due to FIPS mode
> > \n");
> >>> +                g_free(vs->display);
> >>> +                vs->display = NULL;
> >>> +                return -1;
> >>> +            }
> >>>                password = 1; /* Require password auth */
> >>>            } else if (strncmp(options, "reverse", 7) == 0) {
> >>>                reverse = 1;
> >>> diff --git a/ui/vnc.h b/ui/vnc.h
> >>> index a851ebd..8746a98 100644
> >>> --- a/ui/vnc.h
> >>> +++ b/ui/vnc.h
> >>> @@ -160,6 +160,7 @@ struct VncDisplay
> >>>        char *display;
> >>>        char *password;
> >>>        time_t expires;
> >>> +    int fips;
> >>>        int auth;
> >>>        bool lossy;
> >>>        bool non_adaptive;
> >>>
> >>>
> >>>
> >>
> >
> > Regards,
> > George Wilson
>

Regards,
George Wilson
Daniel P. Berrangé May 2, 2012, 9:16 a.m. UTC | #6
On Tue, May 01, 2012 at 06:26:05PM -0500, Anthony Liguori wrote:
> On 05/01/2012 04:20 PM, Paul Moore wrote:
> >FIPS 140-2 requires disabling certain ciphers, including DES, which is used
> >by VNC to obscure passwords when they are sent over the network.  The
> >solution for FIPS users is to disable the use of VNC password auth when the
> >host system is operating in FIPS mode.
> 
> Sorry, what?
> 
> Does FIPS really require software to detect when FIPS is enabled and
> actively disable features???  That's absurd.
> 
> Can you point to another software package that does something like this?

All the SSL libraries for a start (NSS, OpenSSL & GNUTLS).  If we were
using one of those for the VNC DES code we would be disabled.

Regards,
Daniel
Daniel P. Berrangé May 2, 2012, 9:18 a.m. UTC | #7
On Tue, May 01, 2012 at 05:20:40PM -0400, Paul Moore wrote:
> FIPS 140-2 requires disabling certain ciphers, including DES, which is used
> by VNC to obscure passwords when they are sent over the network.  The
> solution for FIPS users is to disable the use of VNC password auth when the
> host system is operating in FIPS mode.
> 
> This patch causes qemu to emits a syslog entry indicating that VNC password
> auth is disabled when it detects the host is running in FIPS mode, and
> unless a VNC password was specified on the command line it continues
> normally.  However, if a VNC password was given on the command line, qemu
> fails with an error message to stderr explaining that that VNC password
> auth is not allowed in FIPS mode.
> 
> Signed-off-by: Paul Moore <pmoore@redhat.com>
> ---
>  qemu-doc.texi |    8 +++++---
>  ui/vnc.c      |   32 ++++++++++++++++++++++++++++++++
>  ui/vnc.h      |    1 +
>  3 files changed, 38 insertions(+), 3 deletions(-)
> 
> diff --git a/qemu-doc.texi b/qemu-doc.texi
> index e5d7ac4..f9b113e 100644
> --- a/qemu-doc.texi
> +++ b/qemu-doc.texi
> @@ -1124,9 +1124,11 @@ the protocol limits passwords to 8 characters it should not be considered
>  to provide high security. The password can be fairly easily brute-forced by
>  a client making repeat connections. For this reason, a VNC server using password
>  authentication should be restricted to only listen on the loopback interface
> -or UNIX domain sockets. Password authentication is requested with the @code{password}
> -option, and then once QEMU is running the password is set with the monitor. Until
> -the monitor is used to set the password all clients will be rejected.
> +or UNIX domain sockets. Password authentication is not supported when operating
> +in FIPS 140-2 compliance mode as it requires the use of the DES cipher. Password
> +authentication is requested with the @code{password} option, and then once QEMU
> +is running the password is set with the monitor. Until the monitor is used to
> +set the password all clients will be rejected.
>  
>  @example
>  qemu [...OPTIONS...] -vnc :1,password -monitor stdio
> diff --git a/ui/vnc.c b/ui/vnc.c
> index deb9ecd..620791e 100644
> --- a/ui/vnc.c
> +++ b/ui/vnc.c
> @@ -32,6 +32,7 @@
>  #include "acl.h"
>  #include "qemu-objects.h"
>  #include "qmp-commands.h"
> +#include <syslog.h>
>  
>  #define VNC_REFRESH_INTERVAL_BASE 30
>  #define VNC_REFRESH_INTERVAL_INC  50
> @@ -48,6 +49,24 @@ static DisplayChangeListener *dcl;
>  static int vnc_cursor_define(VncState *vs);
>  static void vnc_release_modifiers(VncState *vs);
>  
> +static int fips_enabled(void)

s/int/bool/  and use true/false as values

> +{
> +    int enabled = 0;
> +    char value;
> +    FILE *fds;
> +
> +    fds = fopen("/proc/sys/crypto/fips_enabled", "r");
> +    if (fds == NULL) {
> +        return 0;
> +    }
> +    if (fread(&value, sizeof(value), 1, fds) == 1 && value == '1') {
> +        enabled = 1;
> +    }
> +    fclose(fds);
> +
> +    return enabled;
> +}

As already pointed out,wWe should probably make this depend on
__linux__, and 'return false' fo other platforms.

> +
>  static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
>  {
>  #ifdef _VNC_DEBUG
> @@ -2748,6 +2767,12 @@ void vnc_display_init(DisplayState *ds)
>      dcl->idle = 1;
>      vnc_display = vs;
>  
> +    vs->fips = fips_enabled();
> +    VNC_DEBUG("FIPS mode %s\n", (vs->fips ? "enabled" : "disabled"));
> +    if (vs->fips) {
> +        syslog(LOG_NOTICE, "Disabling VNC password auth due to FIPS mode\n");
> +    }

I think this syslog message is better placed in the next chunk of the
patch where you actually test the vs->fips value.

> +
>      vs->lsock = -1;
>  
>      vs->ds = ds;
> @@ -2892,6 +2917,13 @@ int vnc_display_open(DisplayState *ds, const char *display)
>      while ((options = strchr(options, ','))) {
>          options++;
>          if (strncmp(options, "password", 8) == 0) {
> +            if (vs->fips) {
> +                fprintf(stderr,
> +                        "VNC password auth disabled due to FIPS mode\n");
> +                g_free(vs->display);
> +                vs->display = NULL;
> +                return -1;
> +            }
>              password = 1; /* Require password auth */
>          } else if (strncmp(options, "reverse", 7) == 0) {
>              reverse = 1;

Daniel
Daniel P. Berrangé May 2, 2012, 9:29 a.m. UTC | #8
On Tue, May 01, 2012 at 06:45:47PM -0500, Anthony Liguori wrote:
> On 05/01/2012 06:43 PM, George Wilson wrote:
> >
> >Anthony Liguori<anthony@codemonkey.ws>  wrote on 05/01/2012 06:26:05 PM:
> >
> >>Anthony Liguori<anthony@codemonkey.ws>
> >>05/01/2012 06:26 PM
> >>
> >>To
> >>
> >>Paul Moore<pmoore@redhat.com>
> >>
> >>cc
> >>
> >>qemu-devel@nongnu.org, George Wilson/Austin/IBM@IBMUS
> >>
> >>Subject
> >>
> >>Re: [Qemu-devel] [PATCH] vnc: disable VNC password authentication
> >>(security type 2) when in FIPS mode
> >>
> >>On 05/01/2012 04:20 PM, Paul Moore wrote:
> >>>FIPS 140-2 requires disabling certain ciphers, including DES, which is
> >used
> >>>by VNC to obscure passwords when they are sent over the network.  The
> >>>solution for FIPS users is to disable the use of VNC password auth when
> >the
> >>>host system is operating in FIPS mode.
> >>
> >>Sorry, what?
> >>
> >>Does FIPS really require software to detect when FIPS is enabled
> >andactively
> >>disable features???  That's absurd.
> >>
> >>Can you point to another software package that does something like this?
> >
> >Yes, it's true that only FIPS-approved algorithms are permitted for use in
> >FIPS
> >mode.  The kernel and all other FIPS 140-2 validated crypto modules like
> >OpenSSL
> >and NSS are required to restrict algorithms to the approved set.  The
> >kernel
> >sets /proc/sys/crypto/fips_enabled so that programs can detect FIPS mode
> >and
> >behave in accordance with the standard.
> 
> But this is nonsensical. It would allow no-password to be configured
> for the VNC server but not DES?  Why is that okay?  It's not like we
> enable DES passwords by default.  A user has to explicitly configure
> it.

In the wonderful world of security certifications,  "sensible" is
rarely a relevant factor. To answer your point though, FIPS itself
is just about restricting use of insecure algorithms. Whether an
application uses authentication or not, is outside the scope of
that.  Other security standards are responsible for dictating whether
authentication is mandatory or not.

Daniel
Christoph Hellwig May 2, 2012, 10:28 a.m. UTC | #9
On Wed, May 02, 2012 at 12:54:21AM +0200, Andreas F??rber wrote:
> > +    fds = fopen("/proc/sys/crypto/fips_enabled", "r");
> 
> How standardized is this? Should we limit this to __linux__ or something?

It's completelt non-standard and doesn't even exist in mainline Linux.

All the FIPS bullshit is a RHEL-private feature, which is where this patch
should stay as well.
Daniel P. Berrangé May 2, 2012, 11:05 a.m. UTC | #10
On Wed, May 02, 2012 at 12:28:02PM +0200, Christoph Hellwig wrote:
> On Wed, May 02, 2012 at 12:54:21AM +0200, Andreas F??rber wrote:
> > > +    fds = fopen("/proc/sys/crypto/fips_enabled", "r");
> > 
> > How standardized is this? Should we limit this to __linux__ or something?
> 
> It's completelt non-standard and doesn't even exist in mainline Linux.
> 
> All the FIPS bullshit is a RHEL-private feature, which is where this patch
> should stay as well.

You really should check your facts before making such grand assertions
that are trivially disprovable

It *is* in the mainline kernel:

  $ wget https://www.kernel.org/pub/linux/kernel/v3.0/linux-3.3.4.tar.bz2
  $ tar jxvf linux-3.3.4.tar.bz2
  $ cd linux-3.3.4
  $ find | grep -i fips
  ./crypto/fips.c
  ./include/linux/fips.h
  $ find -type f | xargs grep fips_enabled
  ./drivers/char/random.c:		if (fips_enabled) {
  ./crypto/fips.c:int fips_enabled;
  ./crypto/fips.c:EXPORT_SYMBOL_GPL(fips_enabled);
  ./crypto/fips.c:	fips_enabled = !!simple_strtol(str, NULL, 0);
  ./crypto/fips.c:		fips_enabled ? "enabled" : "disabled");
  ./crypto/tcrypt.c:	if (fips_enabled && ret == -EINVAL)
  ./crypto/tcrypt.c:	if (!fips_enabled)
  ./crypto/testmgr.c:		if (fips_enabled && !alg_test_descs[i].fips_allowed)
  ./crypto/testmgr.c:	if (fips_enabled && ((i >= 0 && !alg_test_descs[i].fips_allowed) ||
  ./crypto/testmgr.c:	if (fips_enabled && rc)
  ./crypto/testmgr.c:	if (fips_enabled && !rc)
  ./crypto/proc.c:		.procname       = "fips_enabled",
  ./crypto/proc.c:		.data           = &fips_enabled,
  ./include/linux/fips.h:extern int fips_enabled;
  ./include/linux/fips.h:#define fips_enabled 0


It is *not* solely  "RHEL bullshit":

  $ cat /etc/fedora-release
  Fedora release 17 (Beefy Miracle)
  $ rpm -qf /lib64/libfipscheck.so.1
  fipscheck-lib-1.3.0-3.fc17.x86_64


It *is* in all upstream crypto libraries:

 # wget ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.0.tar.bz2
 # tar jxvf libgcrypt-1.5.0.tar.bz2
 # cd libgcrypt-1.5.0
 # find | grep fips
 ./random/random-fips.c
 ./src/fips.c
 ./tests/fips186-dsa.c
 ./tests/fipsdrv.c
 ./doc/fips-fsm.pdf
 ./doc/fips-fsm.fig
 ./doc/fips-fsm.png
 ./doc/fips-fsm.eps

 # wget http://www.openssl.org/source/openssl-1.0.1b.tar.gz
 # tar zxvf openssl-1.0.1b.tar.gz
 # cd openssl-1.0.1b
 # find | grep fips
 ./test/testfipsssl
 ./crypto/dsa/fips186a.txt
 ./crypto/o_fips.c
 ./crypto/evp/evp_fips.c
 ./crypto/fips_err.h
 ./crypto/fips_ers.c

 # wget ftp://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/NSS_3_13_4_RTM/src/nss-3.13.4.tar.gz
 # tar zxvf nss-3.13.4.tar.gz
 # cd nss-3.13.4
 # find | grep fips
 ./mozilla/security/nss/lib/softoken/fipsaudt.c
 ./mozilla/security/nss/lib/softoken/fipstest.c
 ./mozilla/security/nss/lib/softoken/fipstokn.c
 ./mozilla/security/nss/tests/fips
 ./mozilla/security/nss/tests/fips/fips.sh
 ./mozilla/security/nss/cmd/fipstest
 ./mozilla/security/nss/cmd/fipstest/dsa.sh
 ./mozilla/security/nss/cmd/fipstest/rsa.sh
 ./mozilla/security/nss/cmd/fipstest/manifest.mn
 ./mozilla/security/nss/cmd/fipstest/rng.sh
 ./mozilla/security/nss/cmd/fipstest/fipstest.c
 ./mozilla/security/nss/cmd/fipstest/sha.sh
 ./mozilla/security/nss/cmd/fipstest/hmac.sh
 ./mozilla/security/nss/cmd/fipstest/tdea.sh
 ./mozilla/security/nss/cmd/fipstest/Makefile
 ./mozilla/security/nss/cmd/fipstest/ecdsa.sh
 ./mozilla/security/nss/cmd/fipstest/aes.sh

And fully documented by upstreams too

  http://www.gnupg.org/documentation/manuals/gcrypt/Enabling-FIPS-mode.html
  https://www.mozilla.org/projects/security/pki/nss/fips/
  http://www.openssl.org/docs/fips/fipsnotes.html


Regards,
Daniel
Paul Moore May 2, 2012, 3:45 p.m. UTC | #11
On Wednesday, May 02, 2012 12:54:21 AM Andreas Färber wrote:
> Am 01.05.2012 23:20, schrieb Paul Moore:
> > FIPS 140-2 requires disabling certain ciphers, including DES, which is
> > used
> > by VNC to obscure passwords when they are sent over the network.  The
> > solution for FIPS users is to disable the use of VNC password auth when
> > the
> > host system is operating in FIPS mode.
> > 
> > This patch causes qemu to emits a syslog entry indicating that VNC
> > password
> 
> "to emit"
> 
> > auth is disabled when it detects the host is running in FIPS mode, and
> > unless a VNC password was specified on the command line it continues
> > normally.  However, if a VNC password was given on the command line, qemu
> > fails with an error message to stderr explaining that that VNC password
> 
> "explaining that VNC"

Thanks, typos fixed.

> > auth is not allowed in FIPS mode.
> > 
> > Signed-off-by: Paul Moore <pmoore@redhat.com>
> 
> Interesting feature. :)

It would appear that depends on who you ask :)

> > diff --git a/ui/vnc.c b/ui/vnc.c
> > index deb9ecd..620791e 100644
> > --- a/ui/vnc.c
> > +++ b/ui/vnc.c
> > @@ -32,6 +32,7 @@
> > 
> >  #include "acl.h"
> >  #include "qemu-objects.h"
> >  #include "qmp-commands.h"
> > 
> > +#include <syslog.h>
> 
> syslog.h is POSIX, but it'll need a guard for mingw32.

Is "#ifndef _WIN32" the right guard to use?  Both here and where we make the 
actual syslog() call?

> > @@ -48,6 +49,24 @@ static DisplayChangeListener *dcl;
> > 
> >  static int vnc_cursor_define(VncState *vs);
> >  static void vnc_release_modifiers(VncState *vs);
> > 
> > +static int fips_enabled(void)
> > +{
> > +    int enabled = 0;
> > +    char value;
> > +    FILE *fds;
> > +
> > +    fds = fopen("/proc/sys/crypto/fips_enabled", "r");
> 
> How standardized is this? Should we limit this to __linux__ or something?

It is in the mainline Linux Kernel so fairly standard as far as Linux is 
concerned.  However, it is Linux only to the best of my knowledge so I've gone 
ahead and protected it with __linux__ as you and others have mentioned.

> > +    if (fds == NULL) {
> > +        return 0;
> > +    }
> > +    if (fread(&value, sizeof(value), 1, fds) == 1 && value == '1') {
> > +        enabled = 1;
> > +    }
> > +    fclose(fds);
> > +
> > +    return enabled;
> > +}
> 
> bool would seem nicer as return type and field type below.

Yep, I agree.

I'll post a v2 later today; thanks for taking the time to review the patch and 
send your comments.
Paul Moore May 2, 2012, 3:50 p.m. UTC | #12
On Wednesday, May 02, 2012 10:18:50 AM Daniel P. Berrange wrote:
> On Tue, May 01, 2012 at 05:20:40PM -0400, Paul Moore wrote:
> > diff --git a/ui/vnc.c b/ui/vnc.c
> > index deb9ecd..620791e 100644
> > --- a/ui/vnc.c
> > +++ b/ui/vnc.c
> > @@ -32,6 +32,7 @@
> > 
> >  #include "acl.h"
> >  #include "qemu-objects.h"
> >  #include "qmp-commands.h"
> > 
> > +#include <syslog.h>
> > 
> >  #define VNC_REFRESH_INTERVAL_BASE 30
> >  #define VNC_REFRESH_INTERVAL_INC  50
> > 
> > @@ -48,6 +49,24 @@ static DisplayChangeListener *dcl;
> > 
> >  static int vnc_cursor_define(VncState *vs);
> >  static void vnc_release_modifiers(VncState *vs);
> > 
> > +static int fips_enabled(void)
> 
> s/int/bool/  and use true/false as values

Fixed.
 
> > +{
> > +    int enabled = 0;
> > +    char value;
> > +    FILE *fds;
> > +
> > +    fds = fopen("/proc/sys/crypto/fips_enabled", "r");
> > +    if (fds == NULL) {
> > +        return 0;
> > +    }
> > +    if (fread(&value, sizeof(value), 1, fds) == 1 && value == '1') {
> > +        enabled = 1;
> > +    }
> > +    fclose(fds);
> > +
> > +    return enabled;
> > +}
> 
> As already pointed out,wWe should probably make this depend on
> __linux__, and 'return false' fo other platforms.

Yep, that makes sense.  Fixed.

> >  static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
> >  {
> >  #ifdef _VNC_DEBUG
> > 
> > @@ -2748,6 +2767,12 @@ void vnc_display_init(DisplayState *ds)
> > 
> >      dcl->idle = 1;
> >      vnc_display = vs;
> > 
> > +    vs->fips = fips_enabled();
> > +    VNC_DEBUG("FIPS mode %s\n", (vs->fips ? "enabled" : "disabled"));
> > +    if (vs->fips) {
> > +        syslog(LOG_NOTICE, "Disabling VNC password auth due to FIPS
> > mode\n"); +    }
> 
> I think this syslog message is better placed in the next chunk of the
> patch where you actually test the vs->fips value.

My reasoning for placing it here is so that there would be some positive 
indication that VNC password auth is disabled even if the user isn't 
attempting to use the it.  Although I can understand the reasoning for moving 
it down as well so that things are quieter in the non-passwd-auth case.

With this in mind, do you still think it should be moved down?

Regardless, thanks again for your time and comments.
diff mbox

Patch

diff --git a/qemu-doc.texi b/qemu-doc.texi
index e5d7ac4..f9b113e 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -1124,9 +1124,11 @@  the protocol limits passwords to 8 characters it should not be considered
 to provide high security. The password can be fairly easily brute-forced by
 a client making repeat connections. For this reason, a VNC server using password
 authentication should be restricted to only listen on the loopback interface
-or UNIX domain sockets. Password authentication is requested with the @code{password}
-option, and then once QEMU is running the password is set with the monitor. Until
-the monitor is used to set the password all clients will be rejected.
+or UNIX domain sockets. Password authentication is not supported when operating
+in FIPS 140-2 compliance mode as it requires the use of the DES cipher. Password
+authentication is requested with the @code{password} option, and then once QEMU
+is running the password is set with the monitor. Until the monitor is used to
+set the password all clients will be rejected.
 
 @example
 qemu [...OPTIONS...] -vnc :1,password -monitor stdio
diff --git a/ui/vnc.c b/ui/vnc.c
index deb9ecd..620791e 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -32,6 +32,7 @@ 
 #include "acl.h"
 #include "qemu-objects.h"
 #include "qmp-commands.h"
+#include <syslog.h>
 
 #define VNC_REFRESH_INTERVAL_BASE 30
 #define VNC_REFRESH_INTERVAL_INC  50
@@ -48,6 +49,24 @@  static DisplayChangeListener *dcl;
 static int vnc_cursor_define(VncState *vs);
 static void vnc_release_modifiers(VncState *vs);
 
+static int fips_enabled(void)
+{
+    int enabled = 0;
+    char value;
+    FILE *fds;
+
+    fds = fopen("/proc/sys/crypto/fips_enabled", "r");
+    if (fds == NULL) {
+        return 0;
+    }
+    if (fread(&value, sizeof(value), 1, fds) == 1 && value == '1') {
+        enabled = 1;
+    }
+    fclose(fds);
+
+    return enabled;
+}
+
 static void vnc_set_share_mode(VncState *vs, VncShareMode mode)
 {
 #ifdef _VNC_DEBUG
@@ -2748,6 +2767,12 @@  void vnc_display_init(DisplayState *ds)
     dcl->idle = 1;
     vnc_display = vs;
 
+    vs->fips = fips_enabled();
+    VNC_DEBUG("FIPS mode %s\n", (vs->fips ? "enabled" : "disabled"));
+    if (vs->fips) {
+        syslog(LOG_NOTICE, "Disabling VNC password auth due to FIPS mode\n");
+    }
+
     vs->lsock = -1;
 
     vs->ds = ds;
@@ -2892,6 +2917,13 @@  int vnc_display_open(DisplayState *ds, const char *display)
     while ((options = strchr(options, ','))) {
         options++;
         if (strncmp(options, "password", 8) == 0) {
+            if (vs->fips) {
+                fprintf(stderr,
+                        "VNC password auth disabled due to FIPS mode\n");
+                g_free(vs->display);
+                vs->display = NULL;
+                return -1;
+            }
             password = 1; /* Require password auth */
         } else if (strncmp(options, "reverse", 7) == 0) {
             reverse = 1;
diff --git a/ui/vnc.h b/ui/vnc.h
index a851ebd..8746a98 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -160,6 +160,7 @@  struct VncDisplay
     char *display;
     char *password;
     time_t expires;
+    int fips;
     int auth;
     bool lossy;
     bool non_adaptive;