www.pudn.com > cryptfs030905.rar > fist_cryptfs.c
/* * cryptfs.c * Do not edit by hand. * Automatically generated by fistgen. */ #ifdef HAVE_CONFIG_H # include#endif /* HAVE_CONFIG_H */ #ifdef FISTGEN # include "fist_cryptfs.h" #endif /* FISTGEN */ #include "fist.h" #include "cryptfs.h" /* OPTIONAL CODE FOLLOWS */ unsigned char global_iv[8] = { 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 }; int get_uid_key(const vfs_t *this_vfs, uid_t *uid, BF_KEY *key, dentry_t *dentry) { attached_entry_t *ent; struct list_head *p; int find_uid=0; print_entry_location(); read_lock(&(stopd(this_vfs)->attachlock)); list_for_each(p, &(stopd(this_vfs)->attached)){ ent=list_entry(p,attached_entry_t,list); // printk("uid:%d\n",ent->e_uid); if (ent->e_uid==*uid&&(&ent->e_key)==dtokey(dentry)){ memcpy(key,&(ent->e_key),sizeof(BF_KEY)); find_uid=1; break; } } read_unlock(&(stopd(this_vfs)->attachlock)); if(!find_uid) fist_dprint(8,"The user (uid:%d) cannot get the key\n",(int)*uid); return find_uid; } int cryptfs_encode_block(const char *from, char *to, int len, const vnode_t *this_vnode, const vfs_t *this_vfs, u_long pagenum) { int n = 0; /* internal blowfish variables */ unsigned char iv[8]; BF_KEY key; dentry_t *dentry; struct list_head *p; memcpy(iv, global_iv, 8); /* initialize from global IV */ p=(struct list_head *)&(this_vnode->i_dentry); if(!list_empty(p)){ dentry=list_entry(p->next,dentry_t,d_alias); //printk("try to encode_block in dentry:%s\n",dentry->d_name.name); if(get_uid_key(this_vfs,¤t->fsuid,&key,dentry)){ BF_cfb64_encrypt((char *)from, to, len, &key, iv, &n, BF_ENCRYPT); goto out; } } printk("fail to encode block in inode\n"); memcpy(to,(char*)from,len); out: return len; } int cryptfs_decode_block(const char *from, char *to, int len, const vnode_t *this_vnode, const vfs_t *this_vfs, u_long pagenum) { int n = 0; /* internal blowfish variables */ unsigned char iv[8]; BF_KEY key; struct list_head *p; dentry_t *dentry; memcpy(iv, global_iv, 8); /* initialize from global IV */ p=(struct list_head*) (&this_vnode->i_dentry); if(!list_empty(p)) { dentry=list_entry(p->next,dentry_t,d_alias); printk("cryptfs_decode_block:before get_uid_key\n"); if(get_uid_key(this_vfs,&(current->fsuid),&key,dentry)){ BF_cfb64_encrypt((char *) from, to, len, &key, iv, &n, BF_DECRYPT); goto out; } } memcpy(to,(char*)from,len); out: return len; } int cryptfs_encode_filename(const char *name, int length, char **encoded_name, int skip_dots, const vnode_t *this_vnode, const vfs_t *this_vfs) { char *crypted_name = NULL; const char *ptr; int rounded_length = 0, encoded_length, n, i, j; unsigned char iv[8]; short csum; BF_KEY current_uid_key; void *key; //= &(vfs2priv(this_vfs)->key); dentry_t* dentry; struct list_head *p=(struct list_head*)&this_vnode->i_dentry; if (!list_empty(p)) { dentry=list_entry(p->next,dentry_t,d_alias); //printk("cryptfs_encode_filename:dentry name is %s\n",dentry->d_name.name); if(get_uid_key(this_vfs,¤t->fsuid,¤t_uid_key,dentry)){ key=(void*) ¤t_uid_key; goto encode_filename_getkey; } } // printk("encode filename :cannot find the key for uid:%d\n",(int)current->fsuid); encoded_length=-ENOMEM; goto out; encode_filename_getkey: fist_dprint(8, "ENCODEFILENAME: cleartext filename \"%s\"\n", name); if ((skip_dots && (name[0] == '.' && (length == 1 || (name[1] == '.' && length == 2))))) { encoded_length = length + 1; if (encoded_length > MAXPATHLEN) { /* check for corruption */ encoded_length = -ENAMETOOLONG; goto out; } *encoded_name = kmalloc(encoded_length, GFP_KERNEL); if (!*encoded_name) { encoded_length = -ENOMEM; goto out; } memcpy(*encoded_name, name, length); (*encoded_name)[length] = '\0'; goto out; } for (csum = 0, i = 0, ptr = name; i < length; ptr++, i++) csum += *ptr; /* * rounded_length is an multiple of 3 rounded-up length * the encode algorithm processes 3 source bytes at a time * so we have to make sure we don't read past the memory * we have allocated * * it uses length + 3 to provide 2 bytes for the checksum * and one byte for the length */ rounded_length = (((length + 3) + 2) / 3) * 3; if (rounded_length > MAXPATHLEN) { /* check for corruption */ encoded_length = -ENAMETOOLONG; goto out; } crypted_name = kmalloc(rounded_length, GFP_KERNEL); if (!crypted_name) { encoded_length = -ENOMEM; goto out; } memcpy(iv, global_iv, 8); n = 0; *(short *) crypted_name = csum; crypted_name[2] = length; BF_cfb64_encrypt((char *) name, crypted_name + 3, length, (BF_KEY *) key, iv, &n, BF_ENCRYPT); /* * clear the last few unused bytes * so that we get consistent results from encode */ for (i = length + 3; i < rounded_length; i++) crypted_name[i] = 0; encoded_length = (((length + 3) + 2) / 3) * 4 + 1; if (encoded_length > MAXPATHLEN) { /* check for corruption */ encoded_length = -ENAMETOOLONG; goto out; } *encoded_name = kmalloc(encoded_length, GFP_KERNEL); if (!*encoded_name) { encoded_length = -ENOMEM; goto out; } for (i = 0, j = 0; i < rounded_length; i += 3, j += 4) { (*encoded_name)[j] = 48 + ((crypted_name[i] >> 2) & 63); (*encoded_name)[j + 1] = 48 + (((crypted_name[i] << 4) & 48) | ((crypted_name[i + 1] >> 4) & 15)); (*encoded_name)[j + 2] = 48 + (((crypted_name[i + 1] << 2) & 60) | ((crypted_name[i + 2] >> 6) & 3)); (*encoded_name)[j + 3] = 48 + (crypted_name[i + 2] & 63); } (*encoded_name)[j] = '\0'; out: if (crypted_name) kfree_s(crypted_name, rounded_length); if(*encoded_name) fist_dprint(8, "ENCODEFILENAME: encoded filename \"%s\"\n", *encoded_name); return encoded_length; } int cryptfs_decode_filename(const char *name, int length, char **decrypted_name, int skip_dots, const vnode_t *this_vnode, const vfs_t *this_vfs) { int n, i, j, saved_length, saved_csum, csum; int uudecoded_length, error = 0; unsigned char iv[8]; char *uudecoded_name; BF_KEY current_uid_key; void *key; //= &(vfs2priv(this_vfs)->key); dentry_t* dentry; struct list_head* p=(struct list_head*)&this_vnode->i_dentry; if(!list_empty(p)){ dentry=list_entry(p->next,dentry_t,d_alias); if(get_uid_key(this_vfs,¤t->fsuid,¤t_uid_key,dentry)){ key=(void*) ¤t_uid_key; goto decode_filename_getkey; } } // printk("decode filename :cannot find the key for uid:%d\n",(int)current->fsuid); error=-ENOMEM; goto out; decode_filename_getkey: if ((skip_dots && (name[0] == '.' && (length == 1 || (name[1] == '.' && length == 2))))) { if (length > MAXPATHLEN) { /* check for corruption */ error = -ENAMETOOLONG; goto out; } *decrypted_name = kmalloc(length, GFP_KERNEL); if (!*decrypted_name) { error = -ENOMEM; goto out; } for (i = 0; i < length; i++) (*decrypted_name)[i] = name[i]; error = length; goto out; } if (key == NULL) { error = -EACCES; goto out; } uudecoded_length = ((length + 3) / 4) * 3; if (uudecoded_length > MAXPATHLEN) { /* check for corruption */ error = -ENAMETOOLONG; goto out; } uudecoded_name = kmalloc(uudecoded_length, GFP_KERNEL); if (!uudecoded_name) { error = -ENOMEM; goto out; } for (i = 0, j = 0; i < length; i += 4, j += 3) { uudecoded_name[j] = ((name[i] - 48) <<2) | ((name[i + 1] - 48) >>4); uudecoded_name[j + 1] = (((name[i + 1] - 48) <<4) & 240) | ((name[i + 2] - 48) >>2); uudecoded_name[j + 2] = (((name[i + 2] - 48) <<6) & 192) | ((name[i + 3] - 48) &63); } saved_csum = *(short *) uudecoded_name; saved_length = uudecoded_name[2]; if ((saved_length<1) || (saved_length+1 > MAXPATHLEN)) { /* check for corruption */ error = -ENAMETOOLONG; goto out_free; } if (saved_length > uudecoded_length) { fist_dprint(7, "Problems with the length - too big: %d", saved_length); error = -EACCES; goto out_free; } *decrypted_name = (char *) kmalloc(saved_length+1, GFP_KERNEL); /* +1 for null */ if (!*decrypted_name) { error = -ENOMEM; goto out_free; } (*decrypted_name)[saved_length] = '\0'; /* null terminate */ memcpy(iv, global_iv, 8); n = 0; BF_cfb64_encrypt(uudecoded_name + 3, *decrypted_name, saved_length, (BF_KEY *) key, iv, &n, BF_DECRYPT); for (csum = 0, i = 0; i < saved_length; i++) csum += (*decrypted_name)[i]; if (csum != saved_csum) { fist_dprint(7, "Checksum error\n"); kfree_s(*decrypted_name, saved_length); error = -EACCES; goto out_free; } error = saved_length + 1; out_free: kfree_s(uudecoded_name, uudecoded_length); out: return error; } int fist_get_ioctl_data_SETKEY_ukey(char *buf, int buflen,uid_t *uid, void *arg) { int ret; struct _fist_ioctl_SETKEY this_ioctl; ret = copy_from_user((char *)&this_ioctl, arg, sizeof(this_ioctl)); if (ret != 0) ret = -EFAULT;; if (ret >= 0){ memcpy(buf, &this_ioctl.ukey, buflen); memcpy(uid, &this_ioctl.uid, sizeof(uid_t)); } return ret; } int fist_set_ioctl_data_GETIV_outiv(void *in, int len, void *arg) { int ret; struct _fist_ioctl_GETIV this_ioctl; memcpy(&this_ioctl.outiv, in, len); ret = copy_to_user(arg,(char *)&this_ioctl, sizeof(this_ioctl)); if (ret != 0) ret = -EFAULT;; return ret; }