static int schw_lisener_loop(void* context) { fcry_pt fcpt = NULL; int ret = 0; fcpt = (fcry_pt)context; do { if (kthread_should_stop()) break; wait_for_completion(&fcpt->tsk_started); dprintk("::openrate secure storage!\n"); mutex_lock(&fcpt->mutex); if ((fcpt->cp_src == SCHW_WRITE) || (fcpt->cp_src == SCHW_READ)) { ret = schw_operate_storage(fcpt); if (ret < 0) derr("schw secure storage fail !\n"); } else if (fcpt->cp_src == SCHW_CRYPT) { ret = schw_update_mapblk(fcpt); if (ret < 0) derr("schw secure storage fail !\n"); } mutex_unlock(&fcpt->mutex); if ((fcpt->cp_src == SCHW_WRITE) || (fcpt->cp_src == SCHW_READ) || (fcpt->cp_src == SCHW_CRYPT)) { complete(&fcpt->tsk_end); } }while (!kthread_should_stop()); return 0; }
int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name, int hmac_mode, void *mackey, size_t mackeylen) { int ret; hdata->async.s = crypto_alloc_ahash(alg_name, 0, 0); if (unlikely(IS_ERR(hdata->async.s))) { ddebug(1, "Failed to load transform for %s", alg_name); return -EINVAL; } /* Copy the key from user and set to TFM. */ if (hmac_mode != 0) { ret = crypto_ahash_setkey(hdata->async.s, mackey, mackeylen); if (unlikely(ret)) { ddebug(1, "Setting hmac key failed for %s-%zu.", alg_name, mackeylen*8); ret = -EINVAL; goto error; } } hdata->digestsize = crypto_ahash_digestsize(hdata->async.s); hdata->alignmask = crypto_ahash_alignmask(hdata->async.s); hdata->async.result = kzalloc(sizeof(*hdata->async.result), GFP_KERNEL); if (unlikely(!hdata->async.result)) { ret = -ENOMEM; goto error; } init_completion(&hdata->async.result->completion); hdata->async.request = ahash_request_alloc(hdata->async.s, GFP_KERNEL); if (unlikely(!hdata->async.request)) { derr(0, "error allocating async crypto request"); ret = -ENOMEM; goto error; } ahash_request_set_callback(hdata->async.request, CRYPTO_TFM_REQ_MAY_BACKLOG, cryptodev_complete, hdata->async.result); ret = crypto_ahash_init(hdata->async.request); if (unlikely(ret)) { derr(0, "error in crypto_hash_init()"); goto error_request; } hdata->init = 1; return 0; error_request: ahash_request_free(hdata->async.request); error: kfree(hdata->async.result); crypto_free_ahash(hdata->async.s); return ret; }
static int __init schwdev_init(void) { int rc; dprintk("(%p)\n", schwdev_init); rc = misc_register(&schw_crypto_miscdev); if (rc) { derr(" registration dev failed!\n"); return(rc); } nfcr = kmalloc(sizeof(*nfcr), GFP_KERNEL); if (!nfcr) { derr(" - Malloc failed\n"); return(-ENOMEM); } memset(nfcr, 0, sizeof(*nfcr)); init_completion(&nfcr->tsk_started); init_completion(&nfcr->tsk_end); mutex_init(&nfcr->mutex); INIT_LIST_HEAD(&nfcr->slot_list); nfcr->tsk = kthread_run(schw_lisener_loop, nfcr, "schw"); if (IS_ERR(nfcr->tsk)) { derr("Tsk request fail!\n"); return (-EINVAL); } if (schw_slot_fluqueue(nfcr) < 0) { derr("Flush slot fail!\n"); return (-EINVAL); } return(0); }
/* * Send the command to Swd after the read/write work done * * @param: type[in] request store object type * @param: id [in] store object id * @param: buf [in] buffer if read cmd work done * @param: len [out] actual buffer len * * @return: 0 if ok, otherwise fail. * */ int sst_cmd_work_done( unsigned int type, unsigned int id, char *buf, ssize_t len ) { cmd_t *cmd =(sst_get_aw_storage())->cmd ; int ret = -1 ; mutex_lock(&com_mutex); do{ /* Updata command */ spin_lock(&cmd->lock); sst_memset(cmd, 0 ,sizeof(*cmd)) ; cmd->cmd_type = SST_CMD_WORK_DONE; cmd->cmd_param[0] = type ; cmd->cmd_param[1] = id ; cmd->cmd_buf = buf; cmd->cmd_buf_len = len ; cmd->resp_ret[0] = -1 ; cmd->status = SST_STAS_CMD_RDY ; spin_unlock(&cmd->lock); /* Send the command */ ret = post_cmd_wait_resp( cmd ); if( ret != 0 ){ derr(" respone a fail flag 0x%x\n", ret); mutex_unlock(&com_mutex); return (- EINVAL ); } /* Check response */ if( cmd->resp_ret[0] != SST_RESP_RET_SUCCESS ){ derr(" cmd response fail:0x%x error\n", cmd->resp_ret[0]); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->status != SST_STAS_CMD_RET ){ derr(" cmd status:0x%x error\n", cmd->status); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->resp_type != SST_RESP_READ_DONE &&\ cmd->resp_type != SST_RESP_WRITE_DONE ){ derr(" error in Swd:response type = 0x%x \n", cmd->resp_type); mutex_unlock(&com_mutex); return (- EINVAL ); } }while( false ); mutex_unlock(&com_mutex); return (0); }
int sst_cmd_func_test(char * func_type, char * tagt_type, unsigned int id , unsigned int *pid) { cmd_t *cmd ; int ret = -1 ; cmd= (sst_get_aw_storage())->cmd ; dprintk("sst_cmd_func_test: function [%s] ,target [%s]\n", func_type, tagt_type); mutex_lock(&com_mutex); do{ sst_memset(func_buf, 0 ,128 ); strncpy(func_buf, func_type, 64); strncpy(func_buf+64, tagt_type,64); /* Updata command */ spin_lock(&cmd->lock); sst_memset(cmd, 0 ,sizeof(*cmd)) ; cmd->cmd_type = SST_CMD_FUNC_TEST; cmd->cmd_param[1] = id ; cmd->resp_ret[0] = -1 ; cmd->status = SST_STAS_CMD_RDY ; cmd->cmd_buf = (unsigned char *)func_buf ; cmd->cmd_buf_len =128 ; spin_unlock(&cmd->lock); /* Send the command */ ret = post_cmd_wait_resp( cmd ); if( ret != 0 ){ derr(" respone a fail flag 0x%x\n", ret); mutex_unlock(&com_mutex); return (- EINVAL ); } /* Check response */ if( cmd->resp_ret[0] != SST_RESP_RET_SUCCESS ){ derr(" cmd response fail:0x%x error\n", cmd->resp_ret[0]); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->status != SST_STAS_CMD_RET ){ derr(" cmd status:0x%x error\n", cmd->status); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->resp_type !=SST_RESP_FUNC_TEST_DONE ){ derr(" error in Swd:response type = 0x%x \n", cmd->resp_type); mutex_unlock(&com_mutex); return (- EINVAL ); } if(pid) *pid = cmd->resp_ret[1]; }while( false ); mutex_unlock(&com_mutex); return (0); }
static struct FILE_SIG *_find_file(char *file_name) { struct FILE_SIG *fs ; int crc , slen ; size_t num, size; void * base; base = file_sig_table; num = file_sig_head->actual_cnt ; size = sizeof(struct FILE_SIG); slen = strnlen(file_name,FILE_NAME_LEN); crc = ~crc32_le( ~0, file_name, slen ); dprintk("Find_file debug: name %s, crc 0x%x", file_name, crc); fs = bsearch( &crc, base, num,size,_cmp ); if(!fs){ derr("Find file %s crc fail\n",file_name); return NULL; } if(strncmp(file_name, fs->name, slen)){ derr("Find file %s name fail\n",file_name); return NULL ; } return fs ; }
/* * to create and obtain a new NONBLOCKING socket file descriptor * * (!) this will block SIGRTMIN for this thread only * * returns -1 on error */ int rtsig_install_receiver(int listen_on_rtsig, int nonblock_on) { //make thread "immune" to realtime signals sigset_t immune_set; sigemptyset(&immune_set); sigaddset(&immune_set, (SIGRTMIN+listen_on_rtsig)); pthread_sigmask(SIG_BLOCK, &immune_set, NULL); #if(USS_LIBRARY_DEBUG == 1) //printf("SIGRTMIN=%i\n", (int)SIGRTMIN); //printf("immune to %i\n", (int)SIGRTMIN+listen_on_rtsig); #endif //prepare parameters int fd; sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGRTMIN+listen_on_rtsig); if(nonblock_on != 0) { //create new NONBLOCKING fd for realtime signal SIGRTMIN fd = signalfd(-1, &mask, SFD_NONBLOCK); if(fd == -1) {derr("problem with signal file descriptor"); return USS_ERROR_GENERAL;} } else { //create new NONBLOCKING fd for realtime signal SIGRTMIN fd = signalfd(-1, &mask, 0); if(fd == -1) {derr("problem with signal file descriptor"); return USS_ERROR_GENERAL;} } return fd; }
static int process_verify(struct file *file, char *pathname) { struct inode *inode = file->f_dentry->d_inode; struct FILE_SIG *fs ; int rc = 0; char digest[SHA_DIG_MAX]; struct fivm_path search_fp ={ NULL, 0} ; fivm_gettime("Enter process verication"); if (!fivm_initialized || !S_ISREG(inode->i_mode)) return 0; rc = _find_dir(file,pathname,&search_fp); if(rc != 0){ return 0 ; /*Nothing to do, Just go on */ } fivm_gettime("Find directory name "); fs = _find_file(search_fp.path); if(!fs){ derr("Can't find file %s in sha table\n", search_fp.path); goto out ; } if(fs->flag){ dprintk("Had verified\n"); goto out ; } fivm_gettime("Find file name "); memset(digest, 0 ,SHA_DIG_MAX); rc = fivm_calc_hash(file,digest); if(rc){ derr("fivm_calc_hash fail\n"); goto out ; } fivm_gettime("Calc file digest "); if(memcmp( digest, fs->sha, SHA_DIG_MAX)){ derr("Sha compare fail\n"); derr("Local calculate:\n"); print_hex_dump_bytes("", DUMP_PREFIX_NONE, digest, SHA_DIG_MAX) ; derr("Store value:\n"); print_hex_dump_bytes("", DUMP_PREFIX_NONE, fs->sha,SHA_DIG_MAX ) ; rc = -1; goto out ; } fs->flag =1 ; rc = 0; out: rel_fivm_path(&search_fp); return rc; }
static int _file_meta_read( char *filename, char *buf, ssize_t len, int offset ) { struct file *fd; //ssize_t ret; int retLen = -1; mm_segment_t old_fs ; if(!filename || !buf){ derr("- filename/buf NULL\n"); return (-EINVAL); } old_fs = get_fs(); set_fs(KERNEL_DS); fd = filp_open(filename, O_RDONLY, 0); if(IS_ERR(fd)) { derr(" -file open fail\n"); return -1; } do{ if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) { derr(" -file can't to open!!\n"); break; } if (fd->f_pos != offset) { if (fd->f_op->llseek) { if(fd->f_op->llseek(fd, offset, 0) != offset) { derr(" -failed to seek!!\n"); break; } } else { fd->f_pos = offset; } } retLen = fd->f_op->read(fd, buf, len, &fd->f_pos); }while(false); filp_close(fd, NULL); set_fs(old_fs); return retLen; }
/* This is the main crypto function - feed it with plaintext and get a ciphertext (or vice versa :-) */ static int __crypto_run_std(struct csession *ses_ptr, struct crypt_op *cop) { char *data; char __user *src, *dst; struct scatterlist sg; size_t nbytes, bufsize; int ret = 0; nbytes = cop->len; data = (char *)__get_free_page(GFP_KERNEL); if (unlikely(!data)) { derr(1, "Error getting free page."); return -ENOMEM; } bufsize = PAGE_SIZE < nbytes ? PAGE_SIZE : nbytes; src = cop->src; dst = cop->dst; while (nbytes > 0) { size_t current_len = nbytes > bufsize ? bufsize : nbytes; if (unlikely(copy_from_user(data, src, current_len))) { derr(1, "Error copying %zu bytes from user address %p.", current_len, src); ret = -EFAULT; break; } sg_init_one(&sg, data, current_len); ret = hash_n_crypt(ses_ptr, cop, &sg, &sg, current_len); if (unlikely(ret)) { derr(1, "hash_n_crypt failed."); break; } if (ses_ptr->cdata.init != 0) { if (unlikely(copy_to_user(dst, data, current_len))) { derr(1, "could not copy to user."); ret = -EFAULT; break; } } dst += current_len; nbytes -= current_len; src += current_len; } free_page((unsigned long)data); return ret; }
/* * Send init succeuss command to Swd * * @param: type[in] request store object type * @param: id [in] store object id * @param: buf [in] buffer if read cmd work done * @param: len [out] actual buffer len * * @return: 0 if ok, otherwise fail. * */ int sst_cmd_init_done(void) { cmd_t *cmd =(sst_get_aw_storage())->cmd ; int ret = -1 ; mutex_lock(&com_mutex); do{ /* Updata command */ spin_lock(&cmd->lock); sst_memset(cmd, 0 ,sizeof(*cmd)) ; cmd->cmd_type = SST_CMD_INITIALIZED; cmd->resp_ret[0] = -1 ; cmd->status = SST_STAS_CMD_RDY ; spin_unlock(&cmd->lock); /* Send the command */ ret = post_cmd_wait_resp( cmd ); if( ret != 0 ){ derr(" respone a fail flag 0x%x\n", ret); mutex_unlock(&com_mutex); return (- EINVAL ); } /* Check response */ if( cmd->resp_ret[0] != SST_RESP_RET_SUCCESS ){ derr(" cmd response fail:0x%x error\n", cmd->resp_ret[0]); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->status != SST_STAS_CMD_RET ){ derr(" cmd status:0x%x error\n", cmd->status); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->resp_type !=SST_RESP_INITED_DONE ){ derr(" error in Swd:response type = 0x%x \n", cmd->resp_type); mutex_unlock(&com_mutex); return (- EINVAL ); } }while( false ); mutex_unlock(&com_mutex); return (0); }
static inline int waitfor(struct cryptodev_result *cr, ssize_t ret) { switch (ret) { case 0: break; case -EINPROGRESS: case -EBUSY: wait_for_completion(&cr->completion); /* At this point we known for sure the request has finished, * because wait_for_completion above was not interruptible. * This is important because otherwise hardware or driver * might try to access memory which will be freed or reused for * another request. */ if (unlikely(cr->err)) { derr(0, "error from async request: %d", cr->err); return cr->err; } break; default: return ret; } return 0; }
static ssize_t schw_dev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) { fcry_pt fcr = NULL; int cryp_cnt = 0; int ret = -EFAULT; dprintk("Enter ! count %d\n",count); fcr = filp->private_data; if (fcr == NULL) { derr("file private null!\n"); return -EFAULT; } mutex_lock(&fcr->mutex); cryp_cnt = count + 100; fcr->bpt_len = cryp_cnt; fcr->cp_src = SCHW_READ; fcr->bpt = kmalloc(cryp_cnt, GFP_KERNEL); if (!fcr->bpt) { mutex_unlock(&fcr->mutex); return -ENOMEM; } memset(fcr->bpt, 0, cryp_cnt); if (schw_slot_search(fcr) < 0) goto err_out; mutex_unlock(&fcr->mutex); complete(&fcr->tsk_started); wait_for_completion(&fcr->tsk_end); mutex_lock(&fcr->mutex); if (fcr->status < 0) goto err_out; fcr->encrypted = 0; if (schw_storage_secure(fcr) < 0) goto err_out; if (copy_to_user((char __user *)buf, (void*)fcr->bpt, (unsigned long)fcr->bpt_len)) goto err_out; ret = 0; err_out: kfree(fcr->bpt); fcr->bpt = NULL; fcr->slot = NULL; fcr->bpt_len = 0; fcr->resh_id = -1; fcr->cp_src = SCHW_NONE; mutex_unlock(&fcr->mutex); dprintk("exit ret%d !\n",ret); return (ret==0)?count:ret; }
int cryptodev_hash_reset(struct hash_data *hdata) { int ret; ret = crypto_ahash_init(hdata->async.request); if (unlikely(ret)) { derr(0, "error in crypto_hash_init()"); return ret; } return 0; }
static int __walk_to_root(struct file *file, char *pathname, struct fivm_path *search_fp) { struct dentry *p; char *start , *f_path; int rc = -1 ; int loop, len; mutex_lock(&_fid_mutex); p = file->f_dentry; start = _p_dir + sizeof(_p_dir) -1 ; /*Reserved a null for string end*/ memset(_p_dir, 0, sizeof(_p_dir)); for(loop = 0; loop <16 && p; loop ++, p = p->d_parent){ if( *(p->d_name.name) == '/' ) break; else{ len = strnlen(p->d_name.name, MAX_NAME_LEN); start -= len ; memcpy( start, p->d_name.name, len ); *(--start) ='/'; } } dprintk("FIVM find root path : %s\n", start); if (!memcmp( start, ROOT, sizeof(ROOT)-1 )){ //full file path name len = strnlen(start, FILE_NAME_LEN ); f_path =kmalloc(len, GFP_KERNEL); if(!f_path){ derr("Out of memory\n"); goto out ; } memcpy(f_path, start , len ) ; search_fp->path = f_path; search_fp->flag = FIVM_PART_PATH ; rc = 0; } out: mutex_unlock(&_fid_mutex); return rc ; }
int fivm_enable(void) { #ifdef FIVM_LKM_DEBUG int rc ; rc = read_file_hash_table(); if(rc <0){ derr("read hash table fail\n"); return -1 ; } #endif raw_spin_lock(&fivm_hook_lock); fivm_register_func(_fivm_mmap_verify,_fivm_open_verify); fivm_initialized = 1; raw_spin_unlock(&fivm_hook_lock); return 0 ; }
static int hash_n_crypt(struct csession *ses_ptr, struct crypt_op *cop, struct scatterlist *src_sg, struct scatterlist *dst_sg, uint32_t len) { int ret; /* Always hash before encryption and after decryption. Maybe * we should introduce a flag to switch... TBD later on. */ if (cop->op == COP_ENCRYPT) { if (ses_ptr->hdata.init != 0) { ret = cryptodev_hash_update(&ses_ptr->hdata, src_sg, len); if (unlikely(ret)) goto out_err; } if (ses_ptr->cdata.init != 0) { ret = cryptodev_cipher_encrypt(&ses_ptr->cdata, src_sg, dst_sg, len); if (unlikely(ret)) goto out_err; } } else { if (ses_ptr->cdata.init != 0) { ret = cryptodev_cipher_decrypt(&ses_ptr->cdata, src_sg, dst_sg, len); if (unlikely(ret)) goto out_err; } if (ses_ptr->hdata.init != 0) { ret = cryptodev_hash_update(&ses_ptr->hdata, dst_sg, len); if (unlikely(ret)) goto out_err; } } return 0; out_err: derr(0, "CryptoAPI failure: %d", ret); return ret; }
/* This is the main crypto function - zero-copy edition */ static int __crypto_run_zc(struct csession *ses_ptr, struct kernel_crypt_op *kcop) { struct scatterlist *src_sg, *dst_sg; struct crypt_op *cop = &kcop->cop; int ret = 0; ret = get_userbuf(ses_ptr, cop->src, cop->len, cop->dst, cop->len, kcop->task, kcop->mm, &src_sg, &dst_sg); if (unlikely(ret)) { derr(1, "Error getting user pages. Falling back to non zero copy."); return __crypto_run_std(ses_ptr, cop); } ret = hash_n_crypt(ses_ptr, cop, src_sg, dst_sg, cop->len); release_user_pages(ses_ptr); return ret; }
int main(int argc, char *argv[]) { /* initialize Madagascar */ sf_init(argc, argv); Logger::instance().init("serial-fwi"); FwiParams ¶ms = FwiParams::instance(); std::vector<float> dobs(params.ns * params.nt * params.ng); /* observed data */ std::vector<float> cg(params.nz * params.nx, 0); /* conjugate gradient */ std::vector<float> g0(params.nz * params.nx, 0); /* gradient at previous step */ std::vector<float> wlt(params.nt); /* ricker wavelet */ std::vector<float> objval(params.niter, 0); /* objective/misfit function */ /* initialize wavelet */ rickerWavelet(&wlt[0], params.nt, params.fm, params.dt, params.amp); ShotPosition allSrcPos(params.szbeg, params.sxbeg, params.jsz, params.jsx, params.ns, params.nz); ShotPosition allGeoPos(params.gzbeg, params.gxbeg, params.jgz, params.jgx, params.ng, params.nz); // read velocity Velocity v0 = SfVelocityReader::read(params.vinit, params.nx, params.nz); // read observed data ShotDataReader::serialRead(params.shots, &dobs[0], params.ns, params.nt, params.ng); EnquistAbc2d fmMethod(params.dt, params.dx, params.dz); Velocity vel = fmMethod.expandDomain(v0); float obj0 = 0; for (int iter = 0; iter < params.niter; iter++) { boost::timer::cpu_timer timer; std::vector<float> g1(params.nz * params.nx, 0); /* gradient at curret step */ std::vector<float> derr(params.ns * params.ng * params.nt, 0); /* residual/error between synthetic and observation */ std::vector<float> illum(params.nz * params.nx, 0); /* illumination of the source wavefield */ Velocity vtmp = vel; /* temporary velocity computed with epsil */ fmMethod.bindVelocity(vel); /** * calculate local objective function & derr & illum & g1(gradient) */ float obj = cal_obj_derr_illum_grad(params, &derr[0], &illum[0], &g1[0], &wlt[0], &dobs[0], fmMethod, allSrcPos, allGeoPos); DEBUG() << format("sum_derr %f, sum_illum %f, sum_g1 %f") % sum(derr) % sum(illum) % sum(g1); objval[iter] = iter == 0 ? obj0 = obj, 1.0 : obj / obj0; float epsil = 0; float beta = 0; sf_floatwrite(&illum[0], params.nz * params.nx, params.illums); scale_gradient(&g1[0], &vel.dat[0], &illum[0], params.nz, params.nx, params.precon); bell_smoothz(&g1[0], &illum[0], params.rbell, params.nz, params.nx); bell_smoothx(&illum[0], &g1[0], params.rbell, params.nz, params.nx); sf_floatwrite(&g1[0], params.nz * params.nx, params.grads); DEBUG() << format("before beta: sum_g0: %f, sum_g1: %f, sum_cg: %f") % sum(g0) % sum(g1) % sum(cg); beta = iter == 0 ? 0.0 : cal_beta(&g0[0], &g1[0], &cg[0], params.nz, params.nx); cal_conjgrad(&g1[0], &cg[0], beta, params.nz, params.nx); epsil = cal_epsilon(&vel.dat[0], &cg[0], params.nz, params.nx); cal_vtmp(&vtmp.dat[0], &vel.dat[0], &cg[0], epsil, params.nz, params.nx); std::swap(g1, g0); // let g0 be the previous gradient fmMethod.bindVelocity(vtmp); float alpha = calVelUpdateStepLen(params, &wlt[0], &dobs[0], &derr[0], epsil, fmMethod, allSrcPos, allGeoPos); update_vel(&vel.dat[0], &cg[0], alpha, params.nz, params.nx); sf_floatwrite(&vel.dat[0], params.nz * params.nx, params.vupdates); // output important information at each FWI iteration INFO() << format("iteration %d obj=%f beta=%f epsil=%f alpha=%f") % (iter + 1) % obj % beta % epsil % alpha; // INFO() << timer.format(2); } /// end of iteration sf_floatwrite(&objval[0], params.niter, params.objs); sf_close(); return 0; }
int crypto_run(struct fcrypt *fcr, struct kernel_crypt_op *kcop) { struct csession *ses_ptr; struct crypt_op *cop = &kcop->cop; int ret; if (unlikely(cop->op != COP_ENCRYPT && cop->op != COP_DECRYPT)) { ddebug(1, "invalid operation op=%u", cop->op); return -EINVAL; } /* this also enters ses_ptr->sem */ ses_ptr = crypto_get_session_by_sid(fcr, cop->ses); if (unlikely(!ses_ptr)) { derr(1, "invalid session ID=0x%08X", cop->ses); return -EINVAL; } if (ses_ptr->hdata.init != 0 && (cop->flags == 0 || cop->flags & COP_FLAG_RESET)) { ret = cryptodev_hash_reset(&ses_ptr->hdata); if (unlikely(ret)) { derr(1, "error in cryptodev_hash_reset()"); goto out_unlock; } } if (ses_ptr->cdata.init != 0) { int blocksize = ses_ptr->cdata.blocksize; if (unlikely(cop->len % blocksize)) { derr(1, "data size (%u) isn't a multiple of block size (%u)", cop->len, blocksize); ret = -EINVAL; goto out_unlock; } cryptodev_cipher_set_iv(&ses_ptr->cdata, kcop->iv, min(ses_ptr->cdata.ivsize, kcop->ivlen)); } if (likely(cop->len)) { if (cop->flags & COP_FLAG_NO_ZC) { if (unlikely(ses_ptr->alignmask && !IS_ALIGNED((unsigned long)cop->src, ses_ptr->alignmask))) { dwarning(2, "source address %p is not %d byte aligned - disabling zero copy", cop->src, ses_ptr->alignmask + 1); cop->flags &= ~COP_FLAG_NO_ZC; } if (unlikely(ses_ptr->alignmask && !IS_ALIGNED((unsigned long)cop->dst, ses_ptr->alignmask))) { dwarning(2, "destination address %p is not %d byte aligned - disabling zero copy", cop->dst, ses_ptr->alignmask + 1); cop->flags &= ~COP_FLAG_NO_ZC; } } if (cop->flags & COP_FLAG_NO_ZC) ret = __crypto_run_std(ses_ptr, &kcop->cop); else ret = __crypto_run_zc(ses_ptr, kcop); if (unlikely(ret)) goto out_unlock; } if (ses_ptr->cdata.init != 0) { cryptodev_cipher_get_iv(&ses_ptr->cdata, kcop->iv, min(ses_ptr->cdata.ivsize, kcop->ivlen)); } if (ses_ptr->hdata.init != 0 && ((cop->flags & COP_FLAG_FINAL) || (!(cop->flags & COP_FLAG_UPDATE) || cop->len == 0))) { ret = cryptodev_hash_final(&ses_ptr->hdata, kcop->hash_output); if (unlikely(ret)) { derr(0, "CryptoAPI failure: %d", ret); goto out_unlock; } kcop->digestsize = ses_ptr->hdata.digestsize; } if (ses_ptr->rdata.init != 0 && cop->len > 0) { kcop->rng_output = kmalloc(cop->len, GFP_KERNEL); if (unlikely(!kcop->rng_output)) { derr(0, "Not enough space to store %d random bytes.", cop->len); ret = -ENOMEM; goto out_unlock; } ret = cryptodev_rng_get_bytes(&ses_ptr->rdata, kcop->rng_output, cop->len); // some RNGs return 0 for success, while // some return the number of bytes generated if (unlikely(ret != 0 && ret != cop->len)) { derr(0, "RNG failure: %d", ret); kfree(kcop->rng_output); kcop->rng_output = NULL; goto out_unlock; } ret = 0; kcop->rnglen = cop->len; } out_unlock: crypto_put_session(ses_ptr); return ret; }
static long schw_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int ret = -ENOTTY; fcry_pt fcr = NULL; int id = -1; size_t glen = -1; dprintk("Enter !\n"); fcr = filp->private_data; if (fcr == NULL) { derr("file private null!\n"); return -1; } switch (cmd) { case SCHW_GET_SLOT: dprintk("SCHW_GET_SLOT: \n"); schw_slot_enqueue(fcr); id = fcr->slot->slot_id; if (put_user(id, (int __user *) arg)) return -EFAULT; ret = 0; break; case SCHW_SECURE_LEN: if(copy_from_user((void*)&glen, (void __user *)arg, (unsigned long)sizeof(glen))) return -EFAULT; dprintk("SCHW_SECURE_LEN: \n"); fcr->bpt_len = glen; fcr->bpt = kmalloc(glen, GFP_KERNEL); if (!fcr->bpt) return -ENOMEM; memset(fcr->bpt, 0, glen); put_user(1, (int *)arg); ret = 0; break; case SCHW_SECURE_STORE: dprintk("SCHW_SECURE_STORE: \n"); ret = 0; break; case SCHW_SECURE_PULL: dprintk("SCHW_SECURE_PULL: \n"); ret = 0; break; case SCHW_SET_SLOT: dprintk("SCHW_SET_SLOT: \n"); if(copy_from_user((void*)(&fcr->resh_id),(void __user *)arg, (unsigned long)sizeof(fcr->resh_id))) return -EFAULT; ret = 0; break; case SCHW_SECURE_CLEAR: ret = 0; break; } dprintk("Exit ret%d.....!\n",ret); return ret; }
/* * update secure object data to SWd * * @param: type[in] request store object type * @param: id [in] store object id * @param: src [in] update store object buffer * @param: len [in] buffer len * * @return: 0 if ok, otherwise fail. * */ int sst_cmd_update_object( unsigned int type , unsigned int id , char *src, ssize_t len, char * name ) { cmd_t *cmd = (sst_get_aw_storage())->cmd ; int ret = -1 ; mutex_lock(&com_mutex); do{ /* Updata command */ spin_lock(&cmd->lock); sst_memset(cmd, 0 ,sizeof(*cmd)) ; cmd->cmd_type = SST_CMD_UPDATE_REQ; cmd->cmd_param[0] = type ; cmd->cmd_param[1] = id ; cmd->cmd_buf = src ; cmd->cmd_buf_len = len ; cmd->resp_ret[0] = -1 ; cmd->status = SST_STAS_CMD_RDY; if(name != NULL && id == OEM_DATA ){ cmd->resp_buf = name ; cmd->resp_buf_len = strnlen(name,64) ; } spin_unlock(&cmd->lock); /* Send the command */ ret = post_cmd_wait_resp( cmd ); if( ret != 0 ){ derr(" command procedure error 0x%x\n", ret); mutex_unlock(&com_mutex); return (- EINVAL ); } /* Check response */ if( cmd->resp_ret[0] != SST_RESP_RET_SUCCESS ){ derr(" cmd response fail:0x%x error\n", cmd->resp_ret[0]); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->status != SST_STAS_CMD_RET ){ derr(" cmd status:0x%x error\n", cmd->status); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->resp_type != SST_RESP_UPDATE_DONE ) { derr(" update error in Swd:\ len = 0x%x , response type =0x%x \n", cmd->resp_buf_len, cmd->resp_type); mutex_unlock(&com_mutex); return (- EFAULT ); } } while( false ) ; mutex_unlock(&com_mutex); return (0); }
/* * send binding request for OEM data * * @param: id [in] store object id * @param: src [in] request store object buffer * @param: len [in] buffer len * @param: dst [out] binding result buffer * * @return: 0 if ok, otherwise fail. * */ int sst_cmd_binding_store( unsigned int id , char *src, ssize_t len, char *dst, ssize_t dst_len , ssize_t *retLen ) { cmd_t *cmd = (sst_get_aw_storage())->cmd ; int ret = -1 ; mutex_lock(&com_mutex); do{ /* Updata command */ spin_lock(&cmd->lock); sst_memset(cmd, 0 ,sizeof(*cmd)) ; cmd->cmd_type = SST_CMD_BIND_REQ; cmd->cmd_param[0] = OEM_DATA ; cmd->cmd_param[1] = id ; cmd->cmd_buf = src ; cmd->cmd_buf_len = len ; cmd->resp_buf = dst; cmd->resp_buf_len = dst_len; cmd->resp_ret[0] = -1 ; cmd->status = SST_STAS_CMD_RDY; spin_unlock(&cmd->lock); /* Send the command */ ret = post_cmd_wait_resp( cmd ); if( ret != 0 ){ derr(" command procedure error 0x%x\n", ret); mutex_unlock(&com_mutex); return (- EINVAL ); } /* Check response */ if( cmd->resp_ret[0] != SST_RESP_RET_SUCCESS ){ derr(" cmd response fail:0x%x error\n", cmd->resp_ret[0]); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->status != SST_STAS_CMD_RET ){ derr(" cmd status:0x%x error\n", cmd->status); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->resp_type != SST_RESP_BIND_DONE ) { derr(" bind error in Swd:\ len = 0x%x , response type =0x%x \n", cmd->resp_buf_len, cmd->resp_type); mutex_unlock(&com_mutex); return (- EFAULT ); } *retLen = cmd->resp_ret[1]; } while( false ) ; mutex_unlock(&com_mutex); return (0); }
/* * Send the polling command to Swd * * @param: pret [out] SWd polling work type. * SST_RESP_READ/SST_RESP_WRITE/SST_RESP_DUMMY ... * @param: ptype [out] read or write work from SWd, OEM or USER data * @param: pid [out] read or write work from SWs, 0x01,0x02 ... * @param: buf [in] buffer if polling write cmd from SWd * @param: len [in] buffer len * @param: retLen [out] actual wirte buffer len * * @return: 0 if ok, otherwise fail. * */ int sst_cmd_polling_swd( unsigned int *pret, unsigned int *ptype, unsigned int *pid, char *buf, ssize_t len, ssize_t *retLen ) { cmd_t *cmd = (sst_get_aw_storage())->cmd ; int ret = -1 ; mutex_lock(&com_mutex); do{ /* Updata command */ spin_lock(&cmd->lock); sst_memset(cmd, 0 ,sizeof(*cmd)) ; cmd->cmd_type = SST_CMD_POLLING; cmd->resp_ret[0] = -1 ; cmd->status = SST_STAS_CMD_RDY ; cmd->resp_buf = buf ; cmd->resp_buf_len = len ; spin_unlock(&cmd->lock); /* Send the command */ ret = post_cmd_wait_resp( cmd ); if( ret != 0 ){ derr(" respone a fail flag 0x%x\n", ret); mutex_unlock(&com_mutex); return (- EINVAL ); } /* Check the response */ if( cmd->resp_ret[0] != SST_RESP_RET_SUCCESS ){ derr(" cmd response fail:0x%x error\n", cmd->resp_ret[0]); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->status != SST_STAS_CMD_RET ){ derr(" cmd status:0x%x error\n", cmd->status); mutex_unlock(&com_mutex); return (- EINVAL ); } if( cmd->resp_type != SST_RESP_DUMMY &&\ cmd->resp_type != SST_RESP_READ &&\ cmd->resp_type != SST_RESP_WRITE &&\ cmd->resp_type != SST_RESP_DELETE){ derr(" error in Swd:response type = 0x%x \n", cmd->resp_type); mutex_unlock(&com_mutex); return (- EINVAL ); } *pret = cmd->resp_type; *ptype = cmd->resp_ret[1]; *pid = cmd->resp_ret[2]; *retLen = cmd->resp_ret[3]; }while( false ); mutex_unlock(&com_mutex); return (0); }
static int read_file_hash_table(void) { int cnt,rlen , rc = -1 , offset ; file_sig_head = kzalloc( sizeof(*file_sig_head), GFP_KERNEL); if(!file_sig_head){ derr(" out of memory\n"); return - ENOMEM ; } rlen = sizeof(struct FILE_SIG_HEAD); offset = sizeof(struct FILE_LIST_HEAD); rc = _file_meta_read( (char *)sig_table, (char *)file_sig_head, rlen, offset); if( rc!= rlen || file_sig_head->magic != FILE_SIG_MAGIC ){ derr("Read file %s fail\n", sig_table); rc = - EIO; goto out ; } cnt = file_sig_head->actual_cnt ; if( cnt > DIR_MAX_FILE_NUM ){ derr("out of files count 0x%x\n",cnt); rc = -1 ; goto out ; } rlen = sizeof(struct FILE_SIG)*cnt; file_sig_table = kzalloc(rlen, GFP_KERNEL); if(!file_sig_table){ derr(" out of memory\n"); rc = - ENOMEM ; goto out ; } offset += sizeof(*file_sig_head); rc = _file_meta_read( (char *)sig_table, (char *)file_sig_table, rlen, offset ); if( rc!= rlen){ derr("Read file %s fail\n", sig_table); rc =- EIO; goto out ; } rc = 0 ; out : if(file_sig_table) kfree(file_sig_table); if(file_sig_head ) kfree(file_sig_head); return rc ; }
static ssize_t schw_dev_write(struct file *filp,const char __user *buf, size_t count, loff_t *f_pos) { fcry_pt fcr = NULL; int id = 0; int ret = -EFAULT; dprintk("Enter count%d!\n",count); fcr = filp->private_data; if (fcr == NULL) { derr("file private null!\n"); return -1; } mutex_lock(&fcr->mutex); fcr->bpt_len = count; fcr->cp_src =SCHW_WRITE; fcr->bpt = (unsigned char *)kmalloc(count, GFP_KERNEL); if (!fcr->bpt) { mutex_unlock(&fcr->mutex); return -ENOMEM; } memset(fcr->bpt, 0, count); if(copy_from_user((void*)fcr->bpt, buf, count)) goto err_out; fcr->encrypted = 1; if (schw_storage_secure(fcr) < 0) goto err_out; mutex_unlock(&fcr->mutex); complete(&fcr->tsk_started); wait_for_completion(&fcr->tsk_end); mutex_lock(&fcr->mutex); if (fcr->status < 0) goto err_out; id = fcr->slot->slot_id; fcr->slot = NULL; kfree((void*)fcr->bpt); fcr->bpt = NULL; fcr->bpt_len = 0; fcr->cp_src = SCHW_NONE; fcr->status = -1; mutex_unlock(&fcr->mutex); if (schw_flush_storage(fcr,id) == 0) { fcr->status = -1; ret = 0; } dprintk("exit ret%d!\n",ret); return (ret==0)?count:ret; err_out: fcr->slot = NULL; kfree((void*)fcr->bpt); fcr->bpt = NULL; fcr->bpt_len = 0; fcr->cp_src = SCHW_NONE; mutex_unlock(&fcr->mutex); dprintk("exit ret%d!\n",ret); return ret; }
int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name, uint8_t *keyp, size_t keylen, int stream, int aead) { int ret; if (aead == 0) { struct ablkcipher_alg *alg; out->async.s = crypto_alloc_ablkcipher(alg_name, 0, 0); if (unlikely(IS_ERR(out->async.s))) { ddebug(1, "Failed to load cipher %s", alg_name); return -EINVAL; } alg = crypto_ablkcipher_alg(out->async.s); if (alg != NULL) { /* Was correct key length supplied? */ if (alg->max_keysize > 0 && unlikely((keylen < alg->min_keysize) || (keylen > alg->max_keysize))) { ddebug(1, "Wrong keylen '%zu' for algorithm '%s'. Use %u to %u.", keylen, alg_name, alg->min_keysize, alg->max_keysize); ret = -EINVAL; goto error; } } out->blocksize = crypto_ablkcipher_blocksize(out->async.s); out->ivsize = crypto_ablkcipher_ivsize(out->async.s); out->alignmask = crypto_ablkcipher_alignmask(out->async.s); ret = crypto_ablkcipher_setkey(out->async.s, keyp, keylen); } else { out->async.as = crypto_alloc_aead(alg_name, 0, 0); if (unlikely(IS_ERR(out->async.as))) { ddebug(1, "Failed to load cipher %s", alg_name); return -EINVAL; } out->blocksize = crypto_aead_blocksize(out->async.as); out->ivsize = crypto_aead_ivsize(out->async.as); out->alignmask = crypto_aead_alignmask(out->async.as); ret = crypto_aead_setkey(out->async.as, keyp, keylen); } if (unlikely(ret)) { ddebug(1, "Setting key failed for %s-%zu.", alg_name, keylen*8); ret = -EINVAL; goto error; } out->stream = stream; out->aead = aead; out->async.result = kzalloc(sizeof(*out->async.result), GFP_KERNEL); if (unlikely(!out->async.result)) { ret = -ENOMEM; goto error; } init_completion(&out->async.result->completion); if (aead == 0) { out->async.request = ablkcipher_request_alloc(out->async.s, GFP_KERNEL); if (unlikely(!out->async.request)) { derr(1, "error allocating async crypto request"); ret = -ENOMEM; goto error; } ablkcipher_request_set_callback(out->async.request, CRYPTO_TFM_REQ_MAY_BACKLOG, cryptodev_complete, out->async.result); } else { out->async.arequest = aead_request_alloc(out->async.as, GFP_KERNEL); if (unlikely(!out->async.arequest)) { derr(1, "error allocating async crypto request"); ret = -ENOMEM; goto error; } aead_request_set_callback(out->async.arequest, CRYPTO_TFM_REQ_MAY_BACKLOG, cryptodev_complete, out->async.result); } out->init = 1; return 0; error: if (aead == 0) { if (out->async.request) ablkcipher_request_free(out->async.request); if (out->async.s) crypto_free_ablkcipher(out->async.s); } else { if (out->async.arequest) aead_request_free(out->async.arequest); if (out->async.as) crypto_free_aead(out->async.as); } kfree(out->async.result); return ret; }
/*Get fivm table from user*/ int fivm_set(unsigned long arg) { void *param[4]; void *sh, *st; size_t sh_size, st_size; if( ! access_ok(VERIFY_READ,arg,4) ){ derr("fivm param error\n"); return -EFAULT; } memcpy(param, (void *)arg, sizeof(param)); print_hex_dump_bytes("fivm io param buf:", DUMP_PREFIX_NONE, param, sizeof(param)) ; sh= param[0]; sh_size=(size_t)param[1]; st=param[2]; st_size=(size_t)param[3]; if( sh_size != sizeof(*file_sig_head) || st_size > FILE_NAME_LEN * DIR_MAX_FILE_NUM ){ derr("fivm set buf size error %d:%d\n", sh_size, st_size); return - EFAULT; } file_sig_head = (struct FILE_SIG_HEAD *)kzalloc(sh_size,GFP_KERNEL); if(!file_sig_head || file_sig_table){ derr("out of memory \n"); return -EFAULT ; } if( copy_from_user(file_sig_head, (void __user *) sh, sh_size) ){ derr("fivm sig head buffer from user fail\n"); kfree(file_sig_head); return -EFAULT; } if(st_size != file_sig_head->actual_cnt * sizeof(struct FILE_SIG)){ derr("wrong fivm sig table count\n"); kfree(file_sig_head); return -EFAULT ; } file_sig_table = kzalloc(st_size,GFP_KERNEL); if(!file_sig_table){ derr("out of memory file_sig_table\n"); kfree(file_sig_head); return -EFAULT ; } if( copy_from_user(file_sig_table,(void __user *) st, st_size)){ derr("fivm sig table buffer from user fail\n"); kfree(file_sig_head); kfree(file_sig_table); return -EFAULT; } if(fivm_debug ==1 ){ print_hex_dump_bytes("fivm io sig head buf:", DUMP_PREFIX_NONE, file_sig_head, sh_size ) ; print_hex_dump_bytes("fivm io sig table buf:", DUMP_PREFIX_NONE, file_sig_table, 16 * sizeof(struct FILE_SIG) ) ; } return 0 ; }