Features/Real rng device

From QEMU
Revision as of 07:45, 16 September 2013 by AmosKong (talk | contribs)

Device Description

"QNG PQ4000KU" is USB hardware device, which is used to generate real random data by hardware. The driver name in linux is fsbi_*

We access the device by libqwqng API, QEMU can read random data from a remote socket(server). So we write a CPP program to read data from device and send the data to remote socket(client).

Install libqwqng (reference QWQNG_Linux.pdf in the provided setup-CD)

  • Compile and install the following lib (packages are provided in the setup-CD):
    • libusb-1.0
    • libFTDI1
    • LIBQWQNG-1.3.5
  • Update udev rules to change QNG device's permission
    • create plugdev group if it doesn't exist
    • more detail please reference Section 6 in QWQNG_Linux.pdf
# cp ~/libqwqng-1.3.5/packages/45-libqwqng.rules /etc/udev/rules.d/
# udevadm control --reload-rules
# groupadd plugdev
# usermod -G plugdev -a USER
  • Compile and execute test examples to verify libQWQNG works
host) # cd libqwqng-1.3.5/examples/
host) # make
host) # ./randbytes

Expected result: can read 10 bytes data, which will be converted to hex format.

Read data from dev by QWQNG API

Write a CPP program, add it to "libqwqng-1.3.5/examples/" for compiling

  char* randbyte;
  int bytecount = 10;
  QNG = new QWQNG();
  QNG->RandBytes(randbyte, bytecount))

  delete [] randbyte;
  delete QNG;

Write data to the remote socket

  int sock_fd, accept_sock;
  struct sockaddr_in server_addr;

  server_addr.sin_family=AF_INET;
  server_addr.sin_port=htons(1024);
  server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

  sock_fd = socket(PF_INET, SOCK_STREAM, 0);
  bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(struct sockaddr);
  listen(sock_fd,4);
  accept_sock = accept(sock_fd, NULL, NULL);
  while (1)
    send(accept_sock, randbyte, sizeof(randbyte), 0);

The whole CPP program: VirtRng-RandBytes.cpp

host) # cp libqwqng-1.3.5/examples/RandBytes.cpp libqwqng-1.3.5/examples/RandBytes.cpp.bak
host) # cp RandBytes.cpp libqwqng-1.3.5/examples/
host) # cd libqwqng-1.3.5/examples/
host) # make
host) # ./randbytes

Launch qemu with the virtio-rng backend of socket rng-egd

# qemu-kvm -vnc :0 -snapshot /images/RHEL-Server-6.4-64-virtio.qcow2 \
 -monitor stdio --enable-kvm -m 2000 \
 -chardev socket,host=10.66.4.212,port=1024,id=chr0 \
 -object rng-egd,chardev=chr0,id=rng0 \
 -device virtio-rng-pci,rng=rng0

note: 10.66.4.212 is the IP address of the host that is executing "./randbytes"

Guest can read random data from /dev/hwrng

  guest) # dd if=/dev/hwrng of=/dev/stdout

Expected result: randome data is outputted to the terminal.