Opened 19 months ago

Last modified 19 months ago

#23295 new enhancement

Detect AES-NI hw encryption also if no cpu flags for AES-NI is present

Reported by: naif Owned by:
Priority: Medium Milestone: Tor: unspecified
Component: Core Tor/Tor Version:
Severity: Normal Keywords:
Cc: Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

This ticket is to Detect AES-NI hw encryption also if no cpu flags for AES-NI is present following the testing that has been reported on tor-talk mailing list https://lists.torproject.org/pipermail/tor-talk/2017-August/043450.html .

It seems that a lot of VPS may be able to use AES-NI hardware encryption acceleration, also when CPU flags are not passed by the hypervisor, if we find a way to test the availability of AES-NI presence.

Child Tickets

Change History (7)

comment:1 Changed 19 months ago by yawning

You would have to fork/exec a child process that exercises the instructions and see if it crashes or produces valid output.

I think that doing this automatically is a bad idea, and that the tor daemon should always honor what the CPU self reports.

comment:2 Changed 19 months ago by naif

Isn't possible to execute the AES-NI asm in a try/catch asm statement to evaluate if it's present or not?

comment:3 Changed 19 months ago by nickm

The kind of exception you get from a missing instruction is not the kind that you get from a C++ "throw"; usually it just crashes the process.

You can try to fool around with signal handlers to avoid that, but it's not so portable, and it's usually a bad idea.

comment:4 Changed 19 months ago by nickm

(Unless a try/catch asm statement is some gcc extension?)

comment:5 in reply to:  4 Changed 19 months ago by naif

Replying to nickm:

(Unless a try/catch asm statement is some gcc extension?)

no, no, it's just my ignorance of low-level coding, i where expecting it was possible to try executing a cpu instruction to test it's presence without a crash

comment:6 Changed 19 months ago by dgoulet

Milestone: Tor: unspecified

comment:7 in reply to:  2 Changed 19 months ago by yawning

Replying to naif:

Isn't possible to execute the AES-NI asm in a try/catch asm statement to evaluate if it's present or not?

To add detail to what nickm said, when an illegal instruction is encountered, the CPU generates an interrupt (Invalid Opcode - 0x06). What happens then is OS dependent (because control is passed to the kernel's ISR), but on Linux this gets translated to a SIGILL in the responsible process.

With that in mind, there's two ways to do what you want.

The portable approach:

  • fork()
  • Exercise the AES-NI instructions (all of them, make sure it spits out coherent output) in the child.
  • If the child doesn't get killed AND the tests succeed, think about force enabling AES-NI support.

The fancy approach (What nickm was alluding to):

  • setjmp(), if this returns 0, it means we longjmp()ed from the SIGILL handler and can't use AES-NI.
  • Install a SIGILL handler that will longjmp().
  • Exercise the AES-NI instructions (tests, etc etc etc).
  • If the tests succeed, then think about force enabling AES-NI support.

From past experience, I don't think the portability situation for the signal handler based approach is horrific (and I've abused non-local gotos with signal handlers a decent amount), but there's no benefit to that approach over something fork() based.

That said, personally I would be against doing either, and recommend WONTFIXing this ticket.

The correct way to test for CPU feature support on Intel systems is via CPUID. If the environment is such that CPUID is misreporting it's capabilities, then the environment should be fixed. Just because things happen to appear to work does not mean that features the CPU claims to not support should be enabled.

Note: See TracTickets for help on using tickets.