int Omega_vrfy(void *inner) { assert(inner!=NULL); OmegaInner *self = (OmegaInner*)inner; int ret; BIGNUM *rbn; /* Derive e0~,e1~ from d0, d1 */ rbn = BN_bin2bn(self->h0, self->bytelen_q, self->v_e0); assert(rbn!=NULL); rbn = BN_bin2bn(self->d1, self->bytelen_q, self->v_e1); assert(rbn!=NULL); assert(BN_cmp(self->v_e0, self->e0)==0); assert(BN_cmp(self->v_e1, self->e1)==0); /* Compute a~=g^z*h^(e0+e1) */ ret = BN_mod_exp(self->gz, self->g, self->z, self->p, self->bnctx); assert(ret==1); ret = BN_mod_add(self->e0e1, self->e0, self->e1, self->q, self->bnctx); assert(ret==1); ret = BN_mod_exp(self->he0e1, self->h, self->e0e1, self->p, self->bnctx); assert(ret==1); ret = BN_mod_mul(self->v_a, self->gz, self->he0e1, self->p, self->bnctx); assert(ret==1); assert(BN_cmp(self->v_a, self->a)==0); /* Convert a~ to a~_bytes */ BN2LenBin(self->v_a, self->v_a_bytes, self->bytelen_p); { int i; for (i=0; i<self->bytelen_p; i++) assert(self->v_a_bytes[i]==self->a_bytes[i]); } /* Compute h0~=H(a~bytes||00) */ self->v_a_bytes[self->bytelen_p] = 0x00; VHash(self->v_a_bytes, self->bytelen_p+1, self->v_h0, self->bytelen_red); /* Check h0~==h0 */ int i; int flag = 0; for (i=0; i<self->bytelen_red; i++) flag |= (self->h0[i] != self->v_h0[i]); assert(flag == 0); /* Compute h1~=H(a~bytes||01) */ self->v_a_bytes[self->bytelen_p] = 0x01; VHash(self->v_a_bytes, self->bytelen_p+1, self->v_h1, self->bytelen_rec); /* Copmute m = h1~ xor d1*/ for (i=0; i<self->bytelen_rec; i++) self->v_m[i] = self->v_h1[i]^self->d1[i]; return 0; }
int Omega_sign_offline(void *inner) { assert(inner!=NULL); OmegaInner *self = (OmegaInner*)inner; int ret; BIGNUM *rbn; /* Pick r */ ret = BN_rand_range(self->r, self->q); assert(ret==1); /* Compute a:=g^r mod p */ ret = BN_mod_exp(self->a, self->g, self->r, self->p, self->bnctx); assert(ret==1); /* Convert a into bytes */ int bytelen_a = BN_num_bytes(self->a); assert(bytelen_a <= self->bytelen_p); BN2LenBin(self->a, self->a_bytes, self->bytelen_p); /* Compute h0 = H0(a) = H(a||0x00) */ self->a_bytes[self->bytelen_p] = 0x00; ret = VHash(self->a_bytes, self->bytelen_p+1, self->h0, self->bytelen_red); assert(ret==0); /* Compute h1 = H1(a) = H(a||0x01) */ self->a_bytes[self->bytelen_p] = 0x01; ret = VHash(self->a_bytes, self->bytelen_p+1, self->h1, self->bytelen_rec); assert(ret==0); /* Convert h0(bytes) to e0*/ rbn = BN_bin2bn(self->h0, self->bytelen_q, self->e0); assert(rbn!=NULL); /* Compute re0w = r-e0*w */ ret = BN_mod_mul(self->e0w, self->e0, self->w, self->q, self->bnctx); assert(ret==1); ret = BN_mod_sub(self->re0w, self->r, self->e0w, self->q, self->bnctx); assert(ret==1); return 0; }
int AO_vrfy(void *inner) { assert(inner!=NULL); AOInner *self = (AOInner*)inner; int ret; BIGNUM *rbn; /* e_bytes~ := H(n) */ VHash(self->n, self->bytelen_rec+self->bytelen_red, self->v_e_bytes, self->bytelen_q); /* e~ := int(e_bytes) */ rbn = BN_bin2bn(self->v_e_bytes, self->bytelen_q, self->v_e); assert(rbn!=NULL); /* a~ := g^z * h^e~ */ ret = BN_mod_exp(self->gz, self->g, self->z, self->p, self->bnctx); assert(ret==1); ret = BN_mod_exp(self->he, self->h, self->v_e, self->p, self->bnctx); assert(ret==1); ret = BN_mod_mul(self->v_a, self->gz, self->he, self->p, self->bnctx); assert(ret==1); /* a_bytes~ := bytes(a~) */ BN2LenBin(self->v_a, self->v_am_bytes, self->bytelen_p); /* h2m~ := H2(a_bytes~ || h1~) */ memcpy(&self->v_am_bytes[self->bytelen_p], self->n, self->bytelen_red); VHash(self->v_am_bytes, self->bytelen_p+self->bytelen_red, self->v_mh2, self->bytelen_rec); /* msg~ := mh2~ xor h2 */ BinXor(self->v_mh2, &self->n[self->bytelen_red], self->v_mh2, self->bytelen_rec); /* h1~ := H1(a_bytes~||msg~) */ memcpy(&self->v_am_bytes[self->bytelen_p], self->v_mh2, self->bytelen_rec); VHash(self->v_am_bytes, self->bytelen_p+self->bytelen_rec, self->v_h1, self->bytelen_red); /* Check if h1~ == h1 */ ret = memcmp(self->v_h1, self->n, self->bytelen_red); assert(ret==0); return 0; }
int AO_sign_online(void *inner, char *msg) { assert(inner!=NULL); AOInner *self = (AOInner*)inner; int ret; /* h1 := H1(a_bytes||msg) */ memcpy(&self->am_bytes[self->bytelen_p], msg, self->bytelen_rec); VHash(self->am_bytes, self->bytelen_p+self->bytelen_rec, self->n, self->bytelen_red); /* h2 := H2(a_bytes||h1) xor msg*/ memcpy(&self->am_bytes[self->bytelen_p], self->n, self->bytelen_red); VHash(self->am_bytes, self->bytelen_p+self->bytelen_red, &self->n[self->bytelen_red], self->bytelen_rec); { int i; for (i=0; i<self->bytelen_rec; i++) self->n[self->bytelen_red+i]^=msg[i]; } /* n := h1||h2 * Already done. */ /* e_bytes := H(n) */ ret = VHash(self->n, self->bytelen_rec+self->bytelen_red, self->e_bytes, self->bytelen_q); assert(ret==0); /* e := int(e_bytes) */ BN_bin2bn(self->e_bytes, self->bytelen_q, self->e); /* Compute z = r-e*w */ ret = BN_mod_mul(self->ew, self->e, self->w, self->q, self->bnctx); assert(ret==1); ret = BN_mod_sub(self->z, self->r, self->ew, self->q, self->bnctx); assert(ret==1); /*Convert z to z_bytes */ ret = BN2LenBin(self->z, self->z_bytes, self->bytelen_q); assert(ret==0); return 0; }
/** * Return volume struct if we have it cached and it's up-to-date. * Environment: Must be called with afs_xvolume unlocked. * @param afid Volume FID. * @param locktype * @return Volume or NULL if no result. */ struct volume * afs_FindVolume(struct VenusFid *afid, afs_int32 locktype) { struct volume *tv; afs_int32 i; if (afid == NULL) return NULL; i = VHash(afid->Fid.Volume); ObtainWriteLock(&afs_xvolume, 106); for (tv = afs_volumes[i]; tv; tv = tv->next) { if (tv->volume == afid->Fid.Volume && tv->cell == afid->Cell && (tv->states & VRecheck) == 0) { tv->refCount++; break; } } ReleaseWriteLock(&afs_xvolume); return tv; /* NULL if we didn't find it */ } /*afs_FindVolume */
/** * * @param volid Volume ID. If it's 0, get it from the name. * @param aname Volume name. * @param ve Volume entry. * @param tcell The cell containing this volume. * @param agood * @param type Type of volume. * @param areq Request. * @return Volume or NULL if failure. */ static struct volume * afs_SetupVolume(afs_int32 volid, char *aname, void *ve, struct cell *tcell, afs_int32 agood, afs_int32 type, struct vrequest *areq) { struct volume *tv; struct vldbentry *ove = (struct vldbentry *)ve; struct nvldbentry *nve = (struct nvldbentry *)ve; struct uvldbentry *uve = (struct uvldbentry *)ve; int whichType; /* which type of volume to look for */ int i, j, err = 0; if (!volid) { int len; /* special hint from file server to use vlserver */ len = strlen(aname); if (len >= 8 && strcmp(aname + len - 7, ".backup") == 0) whichType = BACKVOL; else if (len >= 10 && strcmp(aname + len - 9, ".readonly") == 0) whichType = ROVOL; else whichType = RWVOL; /* figure out which one we're really interested in (a set is returned) */ volid = afs_vtoi(aname); if (volid == 0) { if (type == 2) { volid = uve->volumeId[whichType]; } else if (type == 1) { volid = nve->volumeId[whichType]; } else { volid = ove->volumeId[whichType]; } } /* end of if (volid == 0) */ } /* end of if (!volid) */ ObtainWriteLock(&afs_xvolume, 108); i = VHash(volid); for (tv = afs_volumes[i]; tv; tv = tv->next) { if (tv->volume == volid && tv->cell == tcell->cellNum) { break; } } if (!tv) { struct fvolume *tf = 0; tv = afs_GetVolSlot(); if (!tv) { ReleaseWriteLock(&afs_xvolume); return NULL; } memset(tv, 0, sizeof(struct volume)); for (j = fvTable[FVHash(tcell->cellNum, volid)]; j != 0; j = tf->next) { if (afs_FVIndex != j) { struct osi_file *tfile; tfile = osi_UFSOpen(&volumeInode); err = afs_osi_Read(tfile, sizeof(struct fvolume) * j, &staticFVolume, sizeof(struct fvolume)); osi_UFSClose(tfile); if (err != sizeof(struct fvolume)) { afs_warn("afs_SetupVolume: error %d reading volumeinfo\n", (int)err); /* put tv back on the free list; the data in it is not valid */ tv->next = afs_freeVolList; afs_freeVolList = tv; /* staticFVolume contents are not valid */ afs_FVIndex = -1; ReleaseWriteLock(&afs_xvolume); return NULL; } afs_FVIndex = j; } tf = &staticFVolume; if (tf->cell == tcell->cellNum && tf->volume == volid) break; } tv->cell = tcell->cellNum; AFS_RWLOCK_INIT(&tv->lock, "volume lock"); tv->next = afs_volumes[i]; /* thread into list */ afs_volumes[i] = tv; tv->volume = volid; if (tf && (j != 0)) { tv->vtix = afs_FVIndex; tv->mtpoint = tf->mtpoint; tv->dotdot = tf->dotdot; tv->rootVnode = tf->rootVnode; tv->rootUnique = tf->rootUnique; } else { tv->vtix = -1; tv->rootVnode = tv->rootUnique = 0; afs_GetDynrootMountFid(&tv->dotdot); afs_GetDynrootMountFid(&tv->mtpoint); tv->mtpoint.Fid.Vnode = VNUM_FROM_TYPEID(VN_TYPE_MOUNT, tcell->cellIndex << 2); tv->mtpoint.Fid.Unique = volid; } } tv->refCount++; tv->states &= ~VRecheck; /* just checked it */ tv->accessTime = osi_Time(); ReleaseWriteLock(&afs_xvolume); if (type == 2) { LockAndInstallUVolumeEntry(tv, uve, tcell->cellNum, tcell, areq); } else if (type == 1) LockAndInstallNVolumeEntry(tv, nve, tcell->cellNum); else LockAndInstallVolumeEntry(tv, ove, tcell->cellNum); if (agood) { if (!tv->name) { tv->name = afs_osi_Alloc(strlen(aname) + 1); osi_Assert(tv->name != NULL); strcpy(tv->name, aname); } } for (i = 0; i < NMAXNSERVERS; i++) { tv->status[i] = not_busy; } ReleaseWriteLock(&tv->lock); return tv; }