2009-07-15

Events in Qt

Besides the synchronous signal/slot mechanism, Qt also provides an asynchronous communication mechanism: events, which is described by QEvent and its subclasses.

1. trigger/handle an event

An event can be triggered from outside of the application (e.g. mouse move, key press), inside the application (e.g. a timer event described by QTimerEvent), or by a user using QCoreApplication::sendEvent() or QCoreApplication::postEvent().

When an event is received by an object, QObject::event() would be called, which should return true if the event was recognized and processed. This function can be reimplemented as a customized event handler, e.g. QWidget::event() would dispatch a mouse move event to QWidget::mouseMoveEvent().

2. accept an event

We can decide whether an event is accepted or not, by calling QEvent::accept() or QEvent::ignore(). If an event is ignored, it would be sent to the parent of the current handler.

Ignoring an event might be useful in some cases, e.g. you can cancel a request to close a widget by reimplementing QWidget::closeEvent().

3. event filters

Events can be filtered before it reaches the receiver. The filter object can be set by calling the QObject::installEventFilter() function. If more than one filters are installed, the last-installed filter is activated first.

If an event filter is installed, any event would first be sent to it, triggering the QObject::eventFilter() function. This function should return true if the event is to be dropped; otherwise false. Note that it's better to pass the event object to the base class's eventFilter() function, as it might have reimplemented it.

2009-07-14

Remove unused conf files and kernels

Use this command to remove the unused configuration files:
dpkg -l |grep ^rc|awk '{print $2}' |sudo xargs dpkg -P

The following is displayed if there's no remained conf files in the system:
dpkg: --purge needs at least one package name argument

Type dpkg --help for help about installing and deinstalling packages [*];
Use `dselect' or `aptitude' for user-friendly package management;
Type dpkg -Dhelp for a list of dpkg debug flag values;
Type dpkg --force-help for a list of forcing options;
Type dpkg-deb --help for help about manipulating *.deb files;
Type dpkg --license for copyright license and lack of warranty (GNU GPL) [*].

Options marked [*] produce a lot of output - pipe it through `less' or `more' !


To delete the old kernels, use the following command:
sudo aptitude purge ~ilinux-image-.*\(\!`uname -r`\)

2009-07-02

Latest attacks on AES

According to Schneier, researchers from University of Luxembourg proposed a new attack on AES. They presented two related-key boomerang attacks against the full AES-192 and the full AES-256. For the attack against the full AES-256, they successfully reduced the complexity of recovering the key to 2^119; for the (first) attack against the full AES-192, the time complexity is 2^176 and the data complexity is 2^123, as the key schedule of it has better diffusion. Note that their attacks do not apply to AES-128.

Fortunately, as they stated and agreed by Schneier, their attacks are still mainly of theoretical interest and do not present a threat to applications using AES now. However, as Schneier says, it might be a problem for some AES-based SHA-3 candidates.

=========================

Added on 14.7.2009

The best attack against AES-128 so far was published in 2001, which only works on 7 rounds out of 10, with a complexity of 2^128 - 2^119.

2009-07-01

Auto login for XUbuntu

Open Applications --> System --> Login Window, in the Security tab, check the Enable Automatic Login checkbox, and choose the user you want. See a screen shot as below.

2009-06-28

OpenSSL in detail 3: EVP

The EVP provides a high level interface to cryptographic functions, including hashing functions, symmetric/asymmetric encryption/decryption functions, and digital signature functions, etc.

1 initialization

OpenSSL maintains an internal table for all the cryptographic functions, and you should always add the functions to the table first using the following functions.
#include <openssl/evp.h>
void OpenSSL_add_all_algorithms(); // add all algorithms
void OpenSSL_add_all_ciphers(); // add encryption/decryption functions only
void OpenSSL_add_all_digests(); // add hashing functions only
void EVP_cleanup(); // release the algorithms added into the table


2 hashing functions

Two structures are used to describe the usage of hashing functions, EVP_MD to describe the hashing algorithm used, and EVP_MD_CTX to describe the contexts. The following are essential functions.
// if the return type is int, returning a 1 means success, or a 0 means failure

// initialization and cleanup
// initialize and cleanup EVP_MD_CTX
void EVP_MD_CTX_init(EVP_MD_CTX *ctx);
int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx);
// allocate memory, and initialize EVP_MD_CTX
EVP_MD_CTX *EVP_MD_CTX_create(void);
// cleanup and release memory of EVP_MD_CTX
void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx);

// hashing operations
// initialize a hashing operation
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl);
// add information to be hashed
int EVP_DigestUpdate(EVP_MD_CTX *ctx,const void *d, size_t cnt);
// execute the hashing operation and store the result
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx,unsigned char *md, unsigned int *s);


Also, functions like EVP_get_digestbyname() are provided for convenience. The following example shows a basic usage of hashing functions without any error checking.
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
unsigned char digest[EVP_MAX_MD_SIZE] = {0};
int digest_length = 0;
int i = 0;

EVP_MD* md = NULL;
EVP_MD_CTX ctx;

if (argc != 3)
{
printf("usage: digest <algorithm> <message>\n");
exit(EXIT_FAILURE);
}

// add the algorithms
OpenSSL_add_all_digests();

// get the hashing function by name like "SHA256"
md = EVP_get_digestbyname(argv[1]);

// initialize the context for a hashing operation
EVP_MD_CTX_init(&ctx);

// initialize a hashing operation
EVP_DigestInit_ex(&ctx, md, NULL);

// add the information to be hashed, which can be called several times
EVP_DigestUpdate(&ctx, argv[2], strlen(argv[2]));

// execute the hashing operation and store the result
EVP_DigestFinal_ex(&ctx, &digest, &digest_length);

// cleanup
EVP_MD_CTX_cleanup(&ctx);
EVP_cleanup();

// print the result
printf("Digest: ");
for (i = 0; i < digest_length; i++)
{
printf("%2x ", digest[i]);
}
printf("\n");

return EXIT_SUCCESS;
}


3 symmetric encryptions

Two structures are used here, EVP_CIPHER to describe the encryption algorithm, and EVP_CIPHER_CTX to describe the context. The following functions are essential for usage.
// if the return type is int, returning a 1 means success, or a 0 means failure

// initialization and cleanup
// initialize and cleanup EVP_CIPHER_CTX
void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a);
int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
// allocate memory and initialize EVP_CIPHER_CTX
EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void);
// release memory and clean up EVP_CIPHER_CTX
void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a);

// encryption operations
// initialization
// enc as 1 for encryption, 0 for decryption, -1 for unchanging
int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx,const EVP_CIPHER *cipher, ENGINE *impl, const unsigned char *key,const unsigned char *iv, int enc);
// encrypt/decrypt
int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, const unsigned char *in, int inl);
// complete the operation and padding the data by PKCS
int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl);


Now the following example without error checking.
#include <openssl/evp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char** argv)
{
EVP_CIPHER* evp_cipher = NULL;
EVP_CIPHER_CTX evp_cipher_ctx;
char buffer[1024];
int len = 0;
int i = 0;

if (4 != argc)
{
printf("usage: cipher \n");
exit(EXIT_FAILURE);
}

OpenSSL_add_all_ciphers();

// get the encryption algorithm by name like "AES-192-OFB"
evp_cipher = EVP_get_cipherbyname(argv[1]);

// initialize the context
EVP_CIPHER_CTX_init(&evp_cipher_ctx);

// initialize the operation
EVP_CipherInit_ex(&evp_cipher_ctx, evp_cipher, NULL, argv[2], NULL, 1);

// encryption
EVP_CipherUpdate(&evp_cipher_ctx, buffer, &len, argv[3], strlen(argv[3]));

// print the encrypted
printf("Encrypted message: ");
for (i = 0; i < strlen(argv[3]); i++)
{
printf("%2x ", buffer[i]);
}

// cleanup
EVP_CIPHER_CTX_cleanup(&evp_cipher_ctx);
EVP_cleanup();

return EXIT_SUCCESS;
}