/*------------------------------------------------------------------ * Func : mcp_cipher_do_final * * Desc : open function of md dev * * Parm : inode : inode of dev * file : context of file * * Retn : 0 : success, others fail *------------------------------------------------------------------*/ static int mcp_cipher_do_final( MCP_CIPHER_CTX* ctx, unsigned char* out ) { int ret; unsigned char buff[MAX_CIPHER_BLOCK_SIZE]; if (mcp_is_pli_address(out)) { return MCP_CipherFinal(ctx, pli_to_kernel(out)); } else { if ((ret = MCP_CipherFinal(ctx, buff))> 0) { if (copy_to_user((void __user *) out, buff, ret)) return -EFAULT; } return ret; } }
/*------------------------------------------------------------------ * Func : mcp_cipher_do_update * * Desc : open function of md dev * * Parm : inode : inode of dev * file : context of file * * Retn : 0 : success, others fail *------------------------------------------------------------------*/ static int mcp_cipher_do_update( MCP_CIPHER_CTX* ctx, unsigned char* in, unsigned long len, unsigned char* out ) { int outlen; unsigned char* buff = NULL; if (mcp_is_pli_address(in) && mcp_is_pli_address(out)) return MCP_CipherUpdate(ctx, pli_to_kernel(in), len, pli_to_kernel(out)); if ((buff = mcp_malloc(len))==NULL) goto err_alloc_kernel_buffer_failed; if (mcp_is_pli_address(in)) // input buffer is allocated by pli { if ((outlen = MCP_CipherUpdate(ctx, pli_to_kernel(in), len, buff))<0) { printk("[MCP][CIPHER] do cipher update failed, update failed\n"); goto err_update_cipher_failed; } if (copy_to_user((void __user *) out, buff, outlen)) { printk("[MCP][CIPHER] do cipher update failed, copy data to user buffer failed\n"); goto err_copy_to_user_failed; } } else if (mcp_is_pli_address(out)) // output buffer is allocated by pli { if (copy_from_user((void *) buff, (void __user *)in, len)) { printk("[MCP][CIPHER] do cipher update failed, copy data from user space failed\n"); goto err_copy_from_user_failed; } if ((outlen = MCP_CipherUpdate(ctx, buff, len, pli_to_kernel(out)))<0) { printk("[MCP][CIPHER] do cipher update failed, update failed\n"); goto err_update_cipher_failed; } } else // none of them are allocated by pli { if (copy_from_user((void *) buff, (void __user *)in, len)) { printk("[MCP][CIPHER] do cipher update failed, copy data from user space failed\n"); outlen = -EFAULT; goto err_copy_from_user_failed; } if ((outlen = MCP_CipherUpdate(ctx, buff, len, buff))<0) { printk("[MCP][CIPHER] do cipher update failed, update failed\n"); goto err_update_cipher_failed; } if (copy_to_user((void __user *) out, buff, outlen)) { printk("[MCP][CIPHER] do cipher update failed, copy data to user buffer failed\n"); goto err_copy_to_user_failed; } } mcp_free(buff, len); return outlen; //---------------------------------- err_copy_from_user_failed: err_copy_to_user_failed: err_update_cipher_failed: mcp_free(buff, len); err_alloc_kernel_buffer_failed: return -EFAULT; }
/*------------------------------------------------------------------ * Func : mcp_dgst_dev_ioctl * * Desc : ioctl function of md dev * * Parm : inode : inode of dev * file : context of file * cmd : control command * arg : arguments * * Retn : 0 : success, others fail *------------------------------------------------------------------*/ static int mcp_dgst_dev_ioctl( struct inode* inode, struct file* file, unsigned int cmd, unsigned long arg ) { MCP_MD_CTX* ctx = (MCP_MD_CTX*) file->private_data; MCP_BUFF mcpb; MCP_BUFF* kmcpb; unsigned char hash[MCP_MAX_DIGEST_SIZE]; unsigned int hash_len; int ret = -EFAULT; switch (cmd) { case MCP_DGST_IOCTL_INIT: switch(arg) { case MCP_MD_AES_H: return MCP_DigestInit(ctx, MCP_aes_h()); case MCP_MD_MARS_AES_H: return MCP_DigestInit(ctx, MCP_mars_aes_h()); case MCP_MD_SHA1: return MCP_DigestInit(ctx, MCP_sha1()); case MCP_MD_MARS_SHA1: return MCP_DigestInit(ctx, MCP_mars_sha1()); } break; case MCP_DGST_IOCTL_UPDATE: if (copy_from_user((void __user *) &mcpb, (void __user *)arg, sizeof(MCP_BUFF))) { printk("[MCP][DGST] WARNING, do dgst update failed, copy data from user failed\n"); return -EFAULT; } // check is the MCP_buff is valid or not if (mcp_is_pli_address(mcpb.head)) { mcpb.head = pli_to_kernel(mcpb.head); mcpb.data = pli_to_kernel(mcpb.data); mcpb.tail = pli_to_kernel(mcpb.tail); mcpb.end = pli_to_kernel(mcpb.end); ret = MCP_DigestUpdate(ctx, &mcpb); } else { kmcpb = (MCP_BUFF*) ctx->private_data; if (kmcpb) { mcpb_purge(kmcpb); if (mcpb_tailroom(kmcpb) < mcpb.len) { if (kmcpb) free_mcpb(kmcpb); kmcpb = alloc_mcpb(mcpb.len); ctx->private_data = (void*) kmcpb; } } else { kmcpb = alloc_mcpb(mcpb.len); ctx->private_data = (void*) kmcpb; } if (kmcpb==NULL) { printk("[MCP][DGST] WARNING, do dgst update failed, alloc mcpb buffer failed\n"); return -EFAULT; } if (copy_from_user((void *) kmcpb->data, (void __user *)mcpb.data, mcpb.len)==0) { mcpb_put(kmcpb, mcpb.len); ret = MCP_DigestUpdate(ctx, kmcpb); } } return ret; case MCP_DGST_IOCTL_FINAL: if (MCP_DigestFinal(ctx, hash, &hash_len)<0) return -EFAULT; return (copy_to_user((unsigned char __user *)arg, hash, hash_len)<0) ? -EFAULT : hash_len; case MCP_DGST_IOCTL_PEEK: if (MCP_DigestPeek(ctx, hash, &hash_len)<0) return -EFAULT; return (copy_to_user((unsigned char __user *)arg, hash, hash_len)<0) ? -EFAULT : hash_len; default: printk("[MCP][DGST] WARNING, unknown command\n"); return -EFAULT; } return ret; }