I recently had a very interesting experience with SCHANNEL, in particular with TLS authentication.

If you're not familiar with it, SCHANNEL is an example of something called an SSP. It's a Windows implementation of standard authentication protocols, and is included as part of the Windows operating system. If you can figure your way around SSPI (cryptic but relatively small) then you can perform authentication for any network connection with confidence that the security implementation has withstood the test of time.

One of my projects has a network service component which deals with a large number of transactions per unit time. Each transaction involves a new mutually authenticated TLS connection, and the work in setting up those connections was my primary scale-limiting point.

TLS authentication uses asymmetric key cryptography for authentication and validation of credentials. These operations are computationally expensive. As expensive operations, they are the primary limiting factor in my service scalability. Up until recently, I thought a modern machine could only do 10-15 mutual authentications per second. As it turns out, it all depends upon how you set up your connections.

 I was doing the following each time a new client connected:

  1. Bind to the SSP and get function pointers
  2. Create local credentials and prepare to authenticate
  3. Perform authentication activities

I'd thought that the SSP would be cached in memory, so the binding would be cheap. As it turns out, there's a better way to do this: Do (1) and (2) once, and then do (3) as many times as needed for your operations. It's obvious now, but it wasn't with the code base I was working on. As soon as I made this switch, my authentication speeds went up by a factor of 15!

If you need to use SCHANNEL on a server or server-like component, make sure you're not doing extra work for each connection.