encryption - GCM-AEAD support for ubuntu system running linux kernel-3.10 -
i trying implement aead sample code encryption using gcm encryption. invalid argument error while setting key
static int init_aead(void) { printk("starting encryption\n"); struct crypto_aead *tfm = null; struct aead_request *req; struct tcrypt_result tresult; struct scatterlist plaintext[1] ; struct scatterlist ciphertext[1]; struct scatterlist gmactext[1]; unsigned char *plaindata = null; unsigned char *cipherdata = null; unsigned char *gmacdata = null; const u8 *key = kmalloc(16, gfp_kernel); char *algo = "rfc4106(gcm(aes))"; unsigned char *ivp = null; int ret, i, d; unsigned int iv_len; unsigned int keylen = 16; /* allocating cipher handle aead */ tfm = crypto_alloc_aead(algo, 0, 0); init_completion(&tresult.completion); if(is_err(tfm)) { pr_err("alg: aead: failed load transform %s: %ld\n", algo, ptr_err(tfm)); return ptr_err(tfm); } /* allocating request data structure used aead data structure */ req = aead_request_alloc(tfm, gfp_kernel); if(is_err(req)) { pr_err("couldn't allocate request handle %s:\n", algo); return ptr_err(req); } /* allocting callback function used , when request completes */ aead_request_set_callback(req, crypto_tfm_req_may_backlog, aead_work_done,&tresult); crypto_aead_clear_flags(tfm, ~0); /* set key */ get_random_bytes((void*)key, keylen); if((ret = crypto_aead_setkey(tfm, key, 16) != 0)) { pr_err("return value setkey %d\n", ret); pr_info("key not set\n"); ret = -eagain; return ret; } /* set authentication tag length */ if(crypto_aead_setauthsize(tfm, 16)) { pr_info("tag size not authenticated\n"); ret = -eagain; return ret; } /* set iv size */ iv_len = crypto_aead_ivsize(tfm); if (!(iv_len)){ pr_info("iv size not authenticated\n"); ret = -eagain; return ret; } plaindata = kmalloc(16, gfp_kernel); cipherdata = kmalloc(16, gfp_kernel); gmacdata = kmalloc(16, gfp_kernel); ivp = kmalloc(iv_len, gfp_kernel); if(!plaindata || !cipherdata || !gmacdata || !ivp) { printk("memory not availaible\n"); ret = -enomem; return ret; } (i = 0, d = 0; < 16; i++, d++) plaindata[i] = d; memset(cipherdata, 0, 16); memset(gmacdata, 0, 16); (i = 0,d=0xa8; < 16; i++, d++) ivp[i] = d; sg_init_one(&plaintext[0], plaindata, 16); sg_init_one(&ciphertext[0], cipherdata, 16); sg_init_one(&gmactext[0], gmacdata, 128); aead_request_set_crypt(req, plaintext, ciphertext, 16, ivp); aead_request_set_assoc(req, gmactext, 16); ret = crypto_aead_encrypt(req); if (ret) printk("cipher call returns %d \n", ret); else printk("failure \n"); return 0; } module_init(init_aead); module_exit(exit_aead); module_license("gpl"); module_description("my code aead encryption test"); }
on inserting module following output
starting encryption
return value setkey -22
key not set
according aead specification aead uses aes-128 encryption hence block size should 128 bit .
but system shows 1 byte block size support aead
name : rfc4106(gcm(aes)) driver : rfc4106-gcm-aesni module : aesni_intel priority : 400 refcnt : 1 selftest : passed type : nivaead async : yes blocksize : 1 ivsize : 8 maxauthsize : 16 geniv : seqiv
does invalid argument error thrown becuase of block size. if , shall make work ?
the block size of aes indeed 128 bit. block size of gcm different matter though. gcm (galois-counter mode) - name suggests - build on top of ctr (counter) mode of operation, called sic (segmented integer counter) mode of operation. turns aes stream cipher. stream ciphers - definition - have block size of 1 byte (or, more precisely, 1 bit, bit level operations not supported api's).
block size has little key size displayed in call, , argument seem require bytes instead of bits (in key lengths defined).
the size of iv should 12 bytes (the default). otherwise additional calculations may needed gcm implementation (if exist @ all).
Comments
Post a Comment