/*SHELL-AES encryption for plaintexts with a length longer than one block but not a multiple of block length:
parameters follow those of function shellaesEnc
*/
void shellaesEnc_nfb(const u8 key[], const u8 nonce[], const u8 ad[], unsigned long long int adlen, const u8 p[], unsigned long long int ptlen, u8 c[], u8 tag[]){

    u8 V[16], U[16], checksum[16], F[16], keyprime[16], L[16], Lprime[16];
    u8* S;
    u8* I;
    u8* Z;

    unsigned long long int pt_fblen;
    unsigned int pt_nfblen;

    pt_nfblen=ptlen%16;
    pt_fblen=ptlen-pt_nfblen;

    S= (u8 *) malloc(ptlen);
    I= (u8 *) malloc(ptlen);
    Z= (u8 *) malloc(pt_fblen);

    memset(V, 0, 16);
    memset(U, 0, 16);
    memset(checksum, 0, 16);
    memset(keyprime, 0, 16);
    memset(F, 0, 16);
    memset(L, 0, 16);
    memset(Lprime, 0, 16);

    u32 mk[4*d], sk[12*d], rk[44], rkprime[44];

    /*key setup*/
    aesKeySetupEnc(rk, key);
    KeySetupEnc(mk, sk, L, Lprime, keyprime, rk, key);
    aesKeySetupEnc(rkprime, keyprime);

    /*process the plaintext except the last non-full block*/
    PXMAC(mk, sk, L, V, rk, ad, adlen);
    CENC(rkprime, S, F, nonce, ptlen);
    memcpy(I, p, ptlen);
    xor_byte_string(S, I, ptlen);
    checksum_state_string(I, checksum, pt_fblen);
    PXENC(mk, sk, L, V, Z, rk, I, pt_fblen);
    memcpy(U, V, 16);
    XEXLayerEnc(rk, Lprime, Z, c, pt_fblen);
    tagGen(rk, checksum, Lprime, U, F, tag, pt_fblen);

    /*XLS: process the last non-full block*/
    XLS(rk, Lprime, p+pt_fblen, pt_fblen, pt_nfblen, c+pt_fblen, tag);

    /*
    printf("ciphertext is: \n");
    printf_byte_string(c, ptlen);

    printf("tag value is: \n");
    printf_byte_string(tag, 16);
    */

    free(I);
    free(Z);
    free(S);

}
/*SHELL-AES encryption for plaintexts of mutiple blocks long:
parameters follow those of function shellaesEnc
*/
void shellaesEnc_fb(const u8 key[], const u8 nonce[], const u8 ad[], unsigned long long int adlen, const u8 p[], unsigned long long int ptlen, u8 c[], u8 tag[]){
    u8 V[16], U[16], checksum[16], F[16], keyprime[16], L[16], Lprime[16];
    u8* S;
    u8* I;
    u8* Z;

    S= (u8 *) malloc(ptlen);
    I= (u8 *) malloc(ptlen);
    Z= (u8 *) malloc(ptlen);

    memset(V, 0, 16);
    memset(U, 0, 16);
    memset(checksum, 0, 16);
    memset(keyprime, 0, 16);
    memset(F, 0, 16);
    memset(L, 0, 16);
    memset(Lprime, 0, 16);

    u32 mk[4*d], sk[12*d], rk[44], rkprime[44];

    /* key setup */
    aesKeySetupEnc(rk, key);
    KeySetupEnc(mk, sk, L, Lprime, keyprime, rk, key);
    aesKeySetupEnc(rkprime, keyprime);

    /*PXMAC: process associated data, and save output to V[]*/
    PXMAC(mk, sk, L, V, rk, ad, adlen);

    /*CENC: process nonce, and save output to S[] and F[]*/
    CENC(rkprime, S, F, nonce, ptlen);

    /*mask plaintext by xoring the output S[] of CENC, and save it to I[]*/
    memcpy(I, S, ptlen);
    xor_byte_string(p, I, ptlen);

    /*PXENC: save outputs to Z[] and U[] */
    PXENC(mk, sk, L, V, Z, rk, I, ptlen);
    memcpy(U, V, 16);

    /*XEX: produce the ciphertext*/
    XEXLayerEnc(rk, Lprime, Z, c, ptlen);

    /*generate tag*/
    checksum_state_string(I, checksum, ptlen);
    tagGen(rk, checksum, Lprime, U, F, tag, ptlen);

    /*
    printf("ciphertext is: \n");
    printf_byte_string(c, ptlen);

    printf("tag value is: \n");
    printf_byte_string(tag, 16);
    */

    free(I);
    free(Z);
    free(S);
}
Beispiel #3
0
static void
entryInit(Entry *e)
{
	e->gen = 0;
	e->dsize = bsize;
	e->psize = bsize/VtEntrySize*VtEntrySize;
	e->flags = VtEntryActive;
	e->depth = 0;
	e->size = 0;
	memmove(e->score, vtZeroScore, VtScoreSize);
	e->tag = tagGen();
	e->snap = 0;
	e->archive = 0;
}
Beispiel #4
0
/*
 * Change the depth of the source r.
 * The entry e for r is contained in block p.
 */
static int
sourceGrowDepth(Source *r, Block *p, Entry *e, int depth)
{
    Block *b, *bb;
    uint32_t tag;
    int type;
    Entry oe;

    assert(sourceIsLocked(r));
    assert(depth <= VtPointerDepth);

    type = entryType(e);
    b = cacheGlobal(r->fs->cache, e->score, type, e->tag, OReadWrite);
    if(b == nil)
        return 0;

    tag = e->tag;
    if(tag == 0)
        tag = tagGen();

    oe = *e;

    /*
     * Keep adding layers until we get to the right depth
     * or an error occurs.
     */
    while(e->depth < depth) {
        bb = cacheAllocBlock(r->fs->cache, type+1, tag, r->fs->ehi, r->fs->elo);
        if(bb == nil)
            break;
//fprint(2, "alloc %lux grow %V\n", bb->addr, b->score);
        memmove(bb->data, b->score, VtScoreSize);
        memmove(e->score, bb->score, VtScoreSize);
        e->depth++;
        type++;
        e->tag = tag;
        e->flags |= VtEntryLocal;
        blockDependency(bb, b, 0, vtZeroScore, nil);
        blockPut(b);
        b = bb;
        blockDirty(b);
    }

    entryPack(e, p->data, r->offset % r->epb);
    blockDependency(p, b, r->offset % r->epb, nil, &oe);
    blockPut(b);
    blockDirty(p);

    return e->depth == depth;
}
/*verify the validness of the tag T[]*/
int tagVef(const u32 rk[], const u8 checksum[], const u8 Lprime[], const u8 U[], const u8 F[], const u8 T[], unsigned long long int ptlen){

    u8 tempT[16];
    int flag=1;
    int i;

    tagGen(rk, checksum, Lprime, U, F, tempT, ptlen);

    for(i=0; i<16; ++i){
        if(tempT[i]!=T[i]){
            flag=0;
        }
    }
    return flag;
}
/*SHELL-AES decryption for plaintexts with a length longer than one block but not a multiple of block length:
shellaesDec_fb is used to decrypt of the ciphertext without the last non-full block;
parameters follow those of function shellaesEnc
*/
void shellaesDec_fb(const u8 key[], const u8 nonce[], const u8 ad[], unsigned long long int adlen, const u8 c[], unsigned long long int ctlen, u8 p[], u8 tag[]){

    u8 V[16], U[16], checksum[16], keyprime[16], F[16], L[16], Lprime[16];

    u8* S;
    u8* I;
    u8* Z;

    S=(u8 *) malloc(ctlen);
    I=(u8 *) malloc(ctlen);
    Z=(u8 *) malloc(ctlen);

    memset(V, 0, 16);
    memset(U, 0, 16);
    memset(checksum, 0, 16);
    memset(keyprime, 0, 16);
    memset(F, 0, 16);
    memset(L, 0, 16);
    memset(Lprime, 0, 16);

    u32 mk[4*d], sk[12*d], isk[12*d], rk[44], irk[44], rkprime[44];

    aesKeySetupEnc(rk, key);
    aesKeySetupDec(irk, key);
    KeySetupDec(mk, sk, isk, L, Lprime, keyprime, rk, key);
    aesKeySetupEnc(rkprime, keyprime);

    PXMAC(mk, sk, L, V, rk, ad, adlen);

    XEXLayerDec(irk, Lprime, c, Z, ctlen);
    PXDEC(mk, isk, L, V, Z, rk, I, ctlen);
    memcpy(U, V, 16);

    checksum_state_string(I, checksum, ctlen);

    CENC(rkprime, S, F, nonce, ctlen);

    memcpy(p, S, ctlen);
    xor_byte_string(I, p, ctlen);

    tagGen(rk, checksum, Lprime, U, F, tag, ctlen);

    free(I);
    free(S);
    free(Z);


}
Beispiel #7
0
static void
rootMetaInit(Entry *e)
{
	u32int addr;
	u32int tag;
	DirEntry de;
	MetaBlock mb;
	MetaEntry me;

	memset(&de, 0, sizeof(de));
	de.elem = vtStrDup("root");
	de.entry = 0;
	de.gen = 0;
	de.mentry = 1;
	de.mgen = 0;
	de.size = 0;
	de.qid = qid++;
	de.uid = vtStrDup("adm");
	de.gid = vtStrDup("adm");
	de.mid = vtStrDup("adm");
	de.mtime = time(0);
	de.mcount = 0;
	de.ctime = time(0);
	de.atime = time(0);
	de.mode = ModeDir | 0555;

	tag = tagGen();
	addr = blockAlloc(BtData, tag);

	/* build up meta block */
	memset(buf, 0, bsize);
	mbInit(&mb, buf, bsize, bsize/100);
	me.size = deSize(&de);
	me.p = mbAlloc(&mb, me.size);
	assert(me.p != nil);
	dePack(&de, &me);
	mbInsert(&mb, 0, &me);
	mbPack(&mb);
	blockWrite(PartData, addr);
	deCleanup(&de);

	/* build up entry for meta block */
	entryInit(e);
	e->flags |= VtEntryLocal;
 	e->size = bsize;
	e->tag = tag;
	localToGlobal(addr, e->score);
}
Beispiel #8
0
static u32int
rootInit(Entry *e)
{
	ulong addr;
	u32int tag;

	tag = tagGen();

	addr = blockAlloc(BtDir, tag);
	memset(buf, 0, bsize);

	/* root meta data is in the third entry */
	entryPack(e, buf, 2);

	entryInit(e);
	e->flags |= VtEntryDir;
	entryPack(e, buf, 0);

	entryInit(e);
	entryPack(e, buf, 1);

	blockWrite(PartData, addr);

	entryInit(e);
	e->flags |= VtEntryLocal|VtEntryDir;
 	e->size = VtEntrySize*3;
	e->tag = tag;
	localToGlobal(addr, e->score);

	addr = blockAlloc(BtDir, RootTag);
	memset(buf, 0, bsize);
	entryPack(e, buf, 0);

	blockWrite(PartData, addr);

	return addr;
}
/*SHELL-AES decryption for ciphertexts with a length longer than one block but not a multiple of block length:
parameters follow those of function shellaesEnc
*/
int shellaesDec_nfb(const u8 key[], const u8 nonce[], const u8 ad[], unsigned long long int adlen, const u8 c[], unsigned long long int ctlen, u8 p[], const u8 tag[]){
    u8 V[16], U[16], checksum[16], F[16], keyprime[16], L[16], Lprime[16];
    u8* S;
    u8* I;
    u8* Z;
    u8 tempTag[16], tempTag2[16];
    int i, flag;

    unsigned long long int ct_fblen;
    unsigned int ct_nfblen;

    ct_nfblen=ctlen%16;
    ct_fblen=ctlen-ct_nfblen;

    S= (u8 *) malloc(ctlen);
    I= (u8 *) malloc(ctlen);
    Z= (u8 *) malloc(ct_fblen);

    memset(V, 0, 16);
    memset(U, 0, 16);
    memset(checksum, 0, 16);
    memset(keyprime, 0, 16);
    memset(F, 0, 16);
    memset(L, 0, 16);
    memset(Lprime, 0, 16);

    u32 mk[4*d], sk[12*d], isk[12*d], rk[44], irk[44], rkprime[44];

    /*setup key*/
    aesKeySetupEnc(rk, key);
    aesKeySetupDec(irk, key);
    KeySetupDec(mk, sk, isk, L, Lprime, keyprime, rk, key);
    aesKeySetupEnc(rkprime, keyprime);

    /*decrypt the last non-full block*/
    memcpy(tempTag, tag, 16);
    XLSInv(irk, Lprime, c+ct_fblen, ct_fblen, ct_nfblen, p+ct_fblen, tempTag);

    /*process associated data*/
    PXMAC(mk, sk, L, V, rk, ad, adlen);

    /*decryption of XEX layer*/
    XEXLayerDec(irk, Lprime, c, Z, ct_fblen);

    /*decryption of PXENC layer*/
    PXDEC(mk, isk, L, V, Z, rk, I, ct_fblen);
    memcpy(U, V, 16);

    /*process nonce*/
    CENC(rkprime, S, F, nonce, ctlen);

    /*produce plaintext*/
    memcpy(p, I, ct_fblen);
    xor_byte_string(S, p, ct_fblen);

    /*verify the validness of tag*/
    checksum_state_string(I, checksum, ct_fblen);
    tagGen(rk, checksum, Lprime, U, F, tempTag2, ct_fblen);

    flag=1;

    for(i=0; i<16; ++i){
        if(tempTag[i]!=tempTag2[i]){
            flag=0;
        }
    }

    /*

    if(flag){
        printf("the plaintext is: \n");
        printf_byte_string(p, ctlen);
    }
    else{
        printf("the tag is invalid!");
    }
    */

    return flag;

}
Beispiel #10
0
static u32int
ventiRoot(char *host, char *s)
{
	int i, n;
	uchar score[VtScoreSize];
	u32int addr, tag;
	DirEntry de;
	MetaBlock mb;
	MetaEntry me;
	Entry e;
	VtRoot root;

	if(!parseScore(score, s))
		vtFatal("bad score '%s'", s);

	if((z = vtDial(host, 0)) == nil
	|| !vtConnect(z, nil))
		vtFatal("connect to venti: %R");

	tag = tagGen();
	addr = blockAlloc(BtDir, tag);

	ventiRead(score, VtRootType);
	if(!vtRootUnpack(&root, buf))
		vtFatal("corrupted root: vtRootUnpack");
	n = ventiRead(root.score, VtDirType);

	/*
	 * Fossil's vac archives start with an extra layer of source,
	 * but vac's don't.
	 */
	if(n <= 2*VtEntrySize){
		if(!entryUnpack(&e, buf, 0))
			vtFatal("bad root: top entry");
		n = ventiRead(e.score, VtDirType);
	}

	/*
	 * There should be three root sources (and nothing else) here.
	 */
	for(i=0; i<3; i++){
		if(!entryUnpack(&e, buf, i)
		|| !(e.flags&VtEntryActive)
		|| e.psize < 256
		|| e.dsize < 256)
			vtFatal("bad root: entry %d", i);
		fprint(2, "%V\n", e.score);
	}
	if(n > 3*VtEntrySize)
		vtFatal("bad root: entry count");

	blockWrite(PartData, addr);

	/*
	 * Maximum qid is recorded in root's msource, entry #2 (conveniently in e).
	 */
	ventiRead(e.score, VtDataType);
	if(!mbUnpack(&mb, buf, bsize))
		vtFatal("bad root: mbUnpack");
	meUnpack(&me, &mb, 0);
	if(!deUnpack(&de, &me))
		vtFatal("bad root: dirUnpack");
	if(!de.qidSpace)
		vtFatal("bad root: no qidSpace");
	qid = de.qidMax;

	/*
	 * Recreate the top layer of source.
	 */
	entryInit(&e);
	e.flags |= VtEntryLocal|VtEntryDir;
	e.size = VtEntrySize*3;
	e.tag = tag;
	localToGlobal(addr, e.score);

	addr = blockAlloc(BtDir, RootTag);
	memset(buf, 0, bsize);
	entryPack(&e, buf, 0);
	blockWrite(PartData, addr);

	return addr;
}
Beispiel #11
0
static int
sourceShrinkDepth(Source *r, Block *p, Entry *e, int depth)
{
    Block *b, *nb, *ob, *rb;
    uint32_t tag;
    int type, d;
    Entry oe;

    assert(sourceIsLocked(r));
    assert(depth <= VtPointerDepth);

    type = entryType(e);
    rb = cacheGlobal(r->fs->cache, e->score, type, e->tag, OReadWrite);
    if(rb == nil)
        return 0;

    tag = e->tag;
    if(tag == 0)
        tag = tagGen();

    /*
     * Walk down to the new root block.
     * We may stop early, but something is better than nothing.
     */
    oe = *e;

    ob = nil;
    b = rb;
    /* BUG: explain type++.  i think it is a real bug */
    for(d=e->depth; d > depth; d--, type++) {
        nb = cacheGlobal(r->fs->cache, b->data, type-1, tag, OReadWrite);
        if(nb == nil)
            break;
        if(ob!=nil && ob!=rb)
            blockPut(ob);
        ob = b;
        b = nb;
    }

    if(b == rb) {
        blockPut(rb);
        return 0;
    }

    /*
     * Right now, e points at the root block rb, b is the new root block,
     * and ob points at b.  To update:
     *
     *	(i) change e to point at b
     *	(ii) zero the pointer ob -> b
     *	(iii) free the root block
     *
     * p (the block containing e) must be written before
     * anything else.
     */

    /* (i) */
    e->depth = d;
    /* might have been local and now global; reverse cannot happen */
    if(globalToLocal(b->score) == NilBlock)
        e->flags &= ~VtEntryLocal;
    memmove(e->score, b->score, VtScoreSize);
    entryPack(e, p->data, r->offset % r->epb);
    blockDependency(p, b, r->offset % r->epb, nil, &oe);
    blockDirty(p);

    /* (ii) */
    memmove(ob->data, vtZeroScore, VtScoreSize);
    blockDependency(ob, p, 0, b->score, nil);
    blockDirty(ob);

    /* (iii) */
    if(rb->addr != NilBlock)
        blockRemoveLink(p, rb->addr, rb->l.type, rb->l.tag, 1);

    blockPut(rb);
    if(ob!=nil && ob!=rb)
        blockPut(ob);
    blockPut(b);

    return d == depth;
}
Beispiel #12
0
static Block *
blockWalk(Block *p, int index, int mode, Fs *fs, Entry *e)
{
    Block *b;
    Cache *c;
    uint32_t addr;
    int type;
    uint8_t oscore[VtScoreSize], score[VtScoreSize];
    Entry oe;

    c = fs->cache;

    if((p->l.type & BtLevelMask) == 0) {
        assert(p->l.type == BtDir);
        type = entryType(e);
        b = cacheGlobal(c, e->score, type, e->tag, mode);
    } else {
        type = p->l.type - 1;
        b = cacheGlobal(c, p->data + index*VtScoreSize, type, e->tag, mode);
    }

    if(b)
        b->pc = getcallerpc(&p);

    if(b == nil || mode == OReadOnly)
        return b;

    if(p->l.epoch != fs->ehi) {
        fprint(2, "blockWalk: parent not writable\n");
        abort();
    }
    if(b->l.epoch == fs->ehi)
        return b;

    oe = *e;

    /*
     * Copy on write.
     */
    if(e->tag == 0) {
        assert(p->l.type == BtDir);
        e->tag = tagGen();
        e->flags |= VtEntryLocal;
    }

    addr = b->addr;
    b = blockCopy(b, e->tag, fs->ehi, fs->elo);
    if(b == nil)
        return nil;

    b->pc = getcallerpc(&p);
    assert(b->l.epoch == fs->ehi);

    blockDirty(b);
    memmove(score, b->score, VtScoreSize);
    if(p->l.type == BtDir) {
        memmove(e->score, b->score, VtScoreSize);
        entryPack(e, p->data, index);
        blockDependency(p, b, index, nil, &oe);
    } else {
        memmove(oscore, p->data+index*VtScoreSize, VtScoreSize);
        memmove(p->data+index*VtScoreSize, b->score, VtScoreSize);
        blockDependency(p, b, index, oscore, nil);
    }
    blockDirty(p);

    if(addr != NilBlock)
        blockRemoveLink(p, addr, type, e->tag, 0);

    return b;
}