void openCesaSession(void) { unsigned char sha1Key[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x24, 0x68, 0xac, 0xe0, 0x24, 0x68, 0xac, 0xe0, 0x13, 0x57, 0x9b, 0xdf}; /* sizeof(cryptoKey) should be 128 for AES-128 */ unsigned char cryptoKey[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x02, 0x46, 0x8a, 0xce, 0x13, 0x57, 0x9b, 0xdf}; int i; MV_NFP_SEC_SA_ENTRY sa; MV_CESA_OPEN_SESSION os; unsigned short digest_size = 0; memset(&sa, 0, sizeof(MV_NFP_SEC_SA_ENTRY)); memset(&os, 0, sizeof(MV_CESA_OPEN_SESSION)); os.operation = MV_CESA_MAC_THEN_CRYPTO; os.cryptoAlgorithm = MV_CESA_CRYPTO_AES; os.macMode = MV_CESA_MAC_HMAC_SHA1; digest_size = MV_CESA_SHA1_DIGEST_SIZE; os.cryptoMode = MV_CESA_CRYPTO_ECB; for (i = 0; i < sizeof(cryptoKey); i++) os.cryptoKey[i] = cryptoKey[i]; os.cryptoKeyLength = sizeof(cryptoKey); for (i = 0; i < sizeof(sha1Key); i++) os.macKey[i] = sha1Key[i]; os.macKeyLength = sizeof(sha1Key); os.digestSize = digest_size; if (mvCesaSessionOpen(&os, (short *)&(sa.sid))) printk(KERN_INFO "mvCesaSessionOpen failed in %s\n", __func__); }
/* * Open a session. */ static int /*cesa_ocf_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)*/ cesa_ocf_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri) { u32 status = 0, i; u32 count = 0, auth = 0, encrypt =0; struct cesa_ocf_data *cesa_ocf_cur_ses; MV_CESA_OPEN_SESSION cesa_session; MV_CESA_OPEN_SESSION *cesa_ses = &cesa_session; dprintk("%s()\n", __FUNCTION__); if (sid == NULL || cri == NULL) { printk("%s,%d: EINVAL\n", __FILE__, __LINE__); return EINVAL; } /* leave first empty like in other implementations */ for (i = 1; i < CESA_OCF_MAX_SES; i++) { if (cesa_ocf_sessions[i] == NULL) break; } if(i >= CESA_OCF_MAX_SES) { printk("%s,%d: no more sessions \n", __FILE__, __LINE__); return EINVAL; } cesa_ocf_sessions[i] = (struct cesa_ocf_data *) kmalloc(sizeof(struct cesa_ocf_data), GFP_ATOMIC); if (cesa_ocf_sessions[i] == NULL) { cesa_ocf_freesession(NULL, i); printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__); return ENOBUFS; } dprintk("%s,%d: new session %d \n", __FILE__, __LINE__, i); *sid = i; cesa_ocf_cur_ses = cesa_ocf_sessions[i]; memset(cesa_ocf_cur_ses, 0, sizeof(struct cesa_ocf_data)); cesa_ocf_cur_ses->sid_encrypt = -1; cesa_ocf_cur_ses->sid_decrypt = -1; cesa_ocf_cur_ses->frag_wa_encrypt = -1; cesa_ocf_cur_ses->frag_wa_decrypt = -1; cesa_ocf_cur_ses->frag_wa_auth = -1; /* init the session */ memset(cesa_ses, 0, sizeof(MV_CESA_OPEN_SESSION)); count = 1; while (cri) { if(count > 2) { printk("%s,%d: don't support more then 2 operations\n", __FILE__, __LINE__); goto error; } switch (cri->cri_alg) { case CRYPTO_AES_CBC: dprintk("%s,%d: (%d) AES CBC \n", __FILE__, __LINE__, count); cesa_ocf_cur_ses->cipher_alg = cri->cri_alg; cesa_ocf_cur_ses->ivlen = MV_CESA_AES_BLOCK_SIZE; cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_AES; cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC; if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) { printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__); goto error; } memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8); dprintk("%s,%d: key length %d \n", __FILE__, __LINE__, cri->cri_klen/8); cesa_ses->cryptoKeyLength = cri->cri_klen/8; encrypt += count; break; case CRYPTO_3DES_CBC: dprintk("%s,%d: (%d) 3DES CBC \n", __FILE__, __LINE__, count); cesa_ocf_cur_ses->cipher_alg = cri->cri_alg; cesa_ocf_cur_ses->ivlen = MV_CESA_3DES_BLOCK_SIZE; cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_3DES; cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC; if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) { printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__); goto error; } memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8); cesa_ses->cryptoKeyLength = cri->cri_klen/8; encrypt += count; break; case CRYPTO_DES_CBC: dprintk("%s,%d: (%d) DES CBC \n", __FILE__, __LINE__, count); cesa_ocf_cur_ses->cipher_alg = cri->cri_alg; cesa_ocf_cur_ses->ivlen = MV_CESA_DES_BLOCK_SIZE; cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_DES; cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC; if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) { printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__); goto error; } memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8); cesa_ses->cryptoKeyLength = cri->cri_klen/8; encrypt += count; break; case CRYPTO_MD5: case CRYPTO_MD5_HMAC: dprintk("%s,%d: (%d) %sMD5 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_MD5)? "H-":" "); cesa_ocf_cur_ses->auth_alg = cri->cri_alg; cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MD5_DIGEST_SIZE : 12; cesa_ses->macMode = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MAC_MD5 : MV_CESA_MAC_HMAC_MD5; if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) { printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__); goto error; } cesa_ses->macKeyLength = cri->cri_klen/8; memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8); cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen; auth += count; break; case CRYPTO_SHA1: case CRYPTO_SHA1_HMAC: dprintk("%s,%d: (%d) %sSHA1 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_SHA1)? "H-":" "); cesa_ocf_cur_ses->auth_alg = cri->cri_alg; cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_SHA1_DIGEST_SIZE : 12; cesa_ses->macMode = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_MAC_SHA1 : MV_CESA_MAC_HMAC_SHA1; if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) { printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__); goto error; } cesa_ses->macKeyLength = cri->cri_klen/8; memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8); cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen; auth += count; break; default: printk("%s,%d: unknown algo 0x%x\n", __FILE__, __LINE__, cri->cri_alg); goto error; } cri = cri->cri_next; count++; } if((encrypt > 2) || (auth > 2)) { printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__); goto error; } /* create new sessions in HAL */ if(encrypt) { cesa_ses->operation = MV_CESA_CRYPTO_ONLY; /* encrypt session */ if(auth == 1) { cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO; } else if(auth == 2) { cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC; cesa_ocf_cur_ses->encrypt_tn_auth = 1; } else { cesa_ses->operation = MV_CESA_CRYPTO_ONLY; } cesa_ses->direction = MV_CESA_DIR_ENCODE; status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt); if(status != MV_OK) { printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status); goto error; } /* decrypt session */ if( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) { cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC; } else if( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC ) { cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO; } cesa_ses->direction = MV_CESA_DIR_DECODE; status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_decrypt); if(status != MV_OK) { printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status); goto error; } /* preapre one action sessions for case we will need to split an action */ #ifdef CESA_OCF_SPLIT if(( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) || ( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC )) { /* open one session for encode and one for decode */ cesa_ses->operation = MV_CESA_CRYPTO_ONLY; cesa_ses->direction = MV_CESA_DIR_ENCODE; status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_encrypt); if(status != MV_OK) { printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status); goto error; } cesa_ses->direction = MV_CESA_DIR_DECODE; status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_decrypt); if(status != MV_OK) { printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status); goto error; } /* open one session for auth */ cesa_ses->operation = MV_CESA_MAC_ONLY; cesa_ses->direction = MV_CESA_DIR_ENCODE; status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_auth); if(status != MV_OK) { printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status); goto error; } } #endif } else { /* only auth */ cesa_ses->operation = MV_CESA_MAC_ONLY; cesa_ses->direction = MV_CESA_DIR_ENCODE; status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt); if(status != MV_OK) { printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status); goto error; } } return 0; error: cesa_ocf_freesession(NULL, *sid); return EINVAL; }
MV_STATUS mvCesaIfSessionOpen(MV_CESA_OPEN_SESSION *pSession, short *pSid) { return mvCesaSessionOpen(pSession, pSid); }