/* $Id: rospeed.C,v 1.3 2000/07/28 03:20:54 fubob Exp $ */ /* Use this program to benchmark the speed of crypto on typical SFSRO structures (SHA1 time, SHA1 of inode time, etc). */ /* * * Copyright (C) 2000 Kevin Fu (fubob@mit.edu) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */ #include "sfsrodb.h" bool opaque_directory = false; u_int64_t start_tm, end_tm, duration_tm, i; char IV[SFSRO_IVSIZE]; sfs_hash fh; struct itimerval itv; size_t calllen; char *callbuf; sfsro1_signed_fsinfo info; char eightkbuf[8192]; char shabuf[20]; inline u_int64_t get_time () { timeval tv; gettimeofday (&tv, NULL); return (u_int64_t) tv.tv_sec * 1000000 + tv.tv_usec; } void handler_sha (int foo) { end_tm = get_time(); warn << "SHA1 on 8KB blocks\n"; warn << "Time spent: " << end_tm - start_tm << " usec\n"; warn << "Hash/sec: " << i*1000000/(end_tm - start_tm) << "\n\n"; exit (0); } void start_sha () { signal (SIGALRM, handler_sha); signal (SIGINT, handler_sha); signal (SIGTERM, handler_sha); start_tm = get_time(); for (i=0; 1; i++) { sha1_hash (shabuf, eightkbuf, 8192); } } void handler_sigverify (int foo) { end_tm = get_time(); warn << "SFSRO sig verification\n (RW) of typical fsinfo\n"; warn << "Time spent: " << end_tm - start_tm << " usec\n"; warn << "Sig Verification/sec: " << i*1000000/(end_tm - start_tm) << "\n\n"; exit (0); } void start_sigverify () { signal (SIGALRM, handler_sigverify); signal (SIGINT, handler_sigverify); signal (SIGTERM, handler_sigverify); sfs_sig sig; ptr sk; str seckeyfile = "/disk/pu0/fubob/inplace/sfsro/server/rodb/sfs_host_key"; str key = file2wstr (seckeyfile); if (!key) { warn << seckeyfile << ": " << strerror (errno) << "\n"; fatal ("errors!\n"); } else if (!(sk = import_rabin_priv (key, NULL))) { warn << "could not decode " << seckeyfile << "\n"; warn << key << "\n"; fatal ("errors!\n"); } sig = sk->sign (str ((char *) &info, sizeof (info))); start_tm = get_time(); for (i=0; 1; i++) { verify_sfsrosig (&sig, &info, &sk->n); } } void handler_sigcreate (int foo) { end_tm = get_time(); warn << "SFSRO sig creation\n (RW) of typical fsinfo\n"; warn << "Time spent: " << end_tm - start_tm << " usec\n"; warn << "Sig Creation/sec: " << i*1000000/(end_tm - start_tm) << "\n\n"; exit (0); } void start_sigcreate () { signal (SIGALRM, handler_sigcreate); signal (SIGINT, handler_sigcreate); signal (SIGTERM, handler_sigcreate); sfs_sig sig; ptr sk; str seckeyfile = "/disk/pu0/fubob/inplace/sfsro/server/rodb/sfs_host_key"; str key = file2wstr (seckeyfile); if (!key) { warn << seckeyfile << ": " << strerror (errno) << "\n"; fatal ("errors!\n"); } else if (!(sk = import_rabin_priv (key, NULL))) { warn << "could not decode " << seckeyfile << "\n"; warn << key << "\n"; fatal ("errors!\n"); } start_tm = get_time(); for (i=0; 1; i++) { sig = sk->sign (str ((char *) &info, sizeof (info))); } } void handler_fhverify (int foo) { end_tm = get_time(); warn << "SFSRO file handle verification\n (SHA1 hash) of typical inode w/o indirect blocks\n"; warn << "Time spent: " << end_tm - start_tm << " usec\n"; warn << "FH Verification/sec: " << i*1000000/(end_tm - start_tm) << "\n\n"; exit (0); } void start_fhverify () { signal (SIGALRM, handler_fhverify); signal (SIGINT, handler_fhverify); signal (SIGTERM, handler_fhverify); create_sfsrofh (IV, SFSRO_IVSIZE, &fh, callbuf, calllen); start_tm = get_time(); for (i=0; 1; i++) { verify_sfsrofh (IV, SFSRO_IVSIZE, &fh, callbuf, calllen); } } void handler_fhcreate (int foo) { end_tm = get_time(); warn << "SFSRO file handle creation\n (SHA1 hash) of typical inode w/o indirect blocks\n"; warn << "Time spent: " << end_tm - start_tm << " usec\n"; warn << "FH Creation/sec: " << i*1000000/(end_tm - start_tm) << "\n\n"; exit (0); } void start_fhcreate () { signal (SIGALRM, handler_fhcreate); signal (SIGINT, handler_fhcreate); signal (SIGTERM, handler_fhcreate); start_tm = get_time(); for (i=0; 1; i++) { create_sfsrofh (IV, SFSRO_IVSIZE, &fh, callbuf, calllen); } } void sfsrodb_setinode (const struct stat *st, sfsro_inode *inode) { /* SFSRO has implied read-access by all. We only care whether the file is a non-directory executable. Everything else is synthesised by sfsrocd. */ ftypero t; if (S_ISREG (st->st_mode)) { t = ((st->st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) ? SFSROREG_EXEC : SFSROREG); } else if (S_ISDIR (st->st_mode)) t = opaque_directory ? SFSRODIR_OPAQ : SFSRODIR; else if (S_ISLNK (st->st_mode)) t = SFSROLNK; else { warn << "Non-supported file type " << st->st_mode << "\n"; exit (1); } inode->set_type (t); if (inode->type == SFSROLNK) { rpc_clear (*inode->lnk); inode->lnk->nlink = st->st_nlink; // XXX bogus! cannot rely on this number #ifdef SFS_HAVE_STAT_ST_ATIMESPEC inode->lnk->mtime.seconds = st->st_mtimespec.tv_sec; inode->lnk->mtime.nseconds = st->st_mtimespec.tv_nsec; inode->lnk->ctime.seconds = st->st_ctimespec.tv_sec; inode->lnk->ctime.nseconds = st->st_ctimespec.tv_nsec; #else inode->lnk->mtime.seconds = st->st_mtime; inode->lnk->mtime.nseconds = 0; inode->lnk->ctime.seconds = st->st_ctime; inode->lnk->ctime.nseconds = 0; #endif /* SFS_HAVE_ST_ATIMESPEC */ } else { rpc_clear (*inode->reg); inode->reg->nlink = st->st_nlink; // XXX bogus! cannot rely on this number inode->reg->size = 0; inode->reg->used = 0; #ifdef SFS_HAVE_STAT_ST_ATIMESPEC inode->reg->mtime.seconds = st->st_mtimespec.tv_sec; inode->reg->mtime.nseconds = st->st_mtimespec.tv_nsec; inode->reg->ctime.seconds = st->st_ctimespec.tv_sec; inode->reg->ctime.nseconds = st->st_ctimespec.tv_nsec; #else inode->reg->mtime.seconds = st->st_mtime; inode->reg->mtime.nseconds = 0; inode->reg->ctime.seconds = st->st_ctime; inode->reg->ctime.nseconds = 0; #endif /* SFS_HAVE_ST_ATIMESPEC */ // Special for benchmark inode->reg->direct.setsize (SFSRO_NDIR); bzero (inode->reg->direct.base (), SFSRO_NDIR * sizeof (sfs_hash)); } } int main (int argc, char **argv) { setprogname (argv[0]); if (argc != 3) { warn << "Usage: " << argv[0] << " \n"; warn << "0 == fh creation\n"; warn << "1 == fh verification\n"; warn << "2 == signature creation\n"; warn << "3 == signature verification\n"; warn << "4 == SHA1 on 8KB blocks\n"; exit (-1); } duration_tm = atoi (argv[1]); char *path = argv[0]; memset (IV, 0xCA, SFSRO_IVSIZE); memset (eightkbuf, 0xFE, 8192); sfsro_data dat (SFSRO_INODE); calllen = 0; callbuf = NULL; xdrsuio x (XDR_ENCODE); struct stat st; if (lstat (path, &st) < 0) { warn << "lstat failed on " << path << "\n"; exit (-1); } sfsro_inode inode; sfsrodb_setinode (&st, &inode); *dat.inode = inode; if (xdr_sfsro_data (x.xdrp (), &dat)) { calllen = x.uio ()->resid (); callbuf = suio_flatten (x.uio ()); } // fake fsinfo info.type = SFS_ROFSINFO; info.start = time(NULL); info.duration = 86400; memcpy (info.iv.base (), &IV[0], SFSRO_IVSIZE); create_sfsrofh (IV, SFSRO_IVSIZE, &fh, callbuf, calllen); info.rootfh = info.fhdb = fh ; // Done with setup bzero (&itv, sizeof (itv)); itv.it_value.tv_sec = duration_tm; int err; if ((err = setitimer (ITIMER_REAL, &itv, NULL)) != 0) { warn << "setitimer failed " << strerror (errno) << "\n"; exit (-1); } switch (atoi (argv[2])) { case 0: start_fhcreate (); break; case 1: start_fhverify (); break; case 2: start_sigcreate (); break; case 3: start_sigverify (); break; case 4: start_sha (); break; } }