AES cache timing attack

Hal Finney hal at finney.org
Fri Jun 17 12:21:59 EDT 2005


Peter Gutman writes:
> hal at finney.org ("Hal Finney") writes:
> >Steven M. Bellovin writes:
> >> Dan Bernstein has a new cache timing attack on AES:
> >>       http://cr.yp.to/antiforgery/cachetiming-20050414.pdf
> >This is a pretty alarming attack.  
>
> It is?  Recovering a key from a server custom-written to act as an oracle for
> the attacker?  By this I don't even mean the timing-related stuff, but just
> one that just acts as a basic encryption oracle.

Does it though?  Take a look at the code at the end of Dan's paper,
server.c in Appendix A, which I have reproduced below.  It does not appear
to act as an encryption oracle.  It takes the input, which is *random*
(visible in Appendix C), encrypts it and returns the timing it took to
encrypt it.  However, it does not return the encrypted result.

The one extra piece of information it does return is the encryption of
an all-zero packet.  So there is a small element of chosen plaintext
involved.

But for all the rest, as far as I can see a passive eavesdropper on an
encrypted channel with a good timer could make it work.

Hal Finney

===

server.c:

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <openssl/aes.h>

unsigned int timestamp(void)
{
  unsigned int bottom;
  unsigned int top;
  asm volatile(".byte 15;.byte 49" : "=a"(bottom),"=d"(top));
  return bottom;
}

unsigned char key[16];
AES_KEY expanded;
unsigned char zero[16];
unsigned char scrambledzero[16];

void handle(char out[40],char in[],int len)
{
  unsigned char workarea[len * 3];
  int i;

  for (i = 0;i < 40;++i) out[i] = 0;
  *(unsigned int *) (out + 32) = timestamp();

  if (len < 16) return;
  for (i = 0;i < 16;++i) out[i] = in[i];

  for (i = 16;i < len;++i) workarea[i] = in[i];
  AES_encrypt(in,workarea,&expanded);
  /* a real server would now check AES-based authenticator, */
  /* process legitimate packets, and generate useful output */

  for (i = 0;i < 16;++i) out[16 + i] = scrambledzero[i];
  *(unsigned int *) (out + 36) = timestamp();
}

struct sockaddr_in server;
struct sockaddr_in client; socklen_t clientlen;
int s;
char in[1537];
int r;
char out[40];

main(int argc,char **argv)
{
  if (read(0,key,sizeof key) < sizeof key) return 111;
  AES_set_encrypt_key(key,128,&expanded);
  AES_encrypt(zero,scrambledzero,&expanded);

  if (!argv[1]) return 100;
  if (!inet_aton(argv[1],&server.sin_addr)) return 100;
  server.sin_family = AF_INET;
  server.sin_port = htons(10000);

  s = socket(AF_INET,SOCK_DGRAM,0);
  if (s == -1) return 111;
  if (bind(s,(struct sockaddr *) &server,sizeof server) == -1)
    return 111;

  for (;;) {
    clientlen = sizeof client;
    r = recvfrom(s,in,sizeof in,0
      ,(struct sockaddr *) &client,&clientlen);
    if (r < 16) continue;
    if (r >= sizeof in) continue;
    handle(out,in,r);
    sendto(s,out,40,0,(struct sockaddr *) &client,clientlen);
  }
}

---------------------------------------------------------------------
The Cryptography Mailing List
Unsubscribe by sending "unsubscribe cryptography" to majordomo at metzdowd.com



More information about the cryptography mailing list