Features/Real rng device

From QEMU
Revision as of 07:24, 16 September 2013 by AmosKong (talk | contribs) (Created page with '<<TableOfContents()>> === Device Description === "QNG PQ4000KU" is USB hardware device, which is used to generate real random data by hardware. The driver name in linux is fsb…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

<<TableOfContents()>>


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

{{{

  1. cp ~/libqwqng-1.3.5/packages/45-libqwqng.rules /etc/udev/rules.d/
  2. udevadm control --reload-rules
  3. groupadd plugdev
  4. 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

{{{

  1. 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.