Esempio n. 1
0
/*
 * Read a container with the provided key
 * Read all files and place them into the provided list
 * Returns:
 * >0   Number of read files
 * -1   File error during reading
 * -2   Wrong password in input
 */
int memfile_readfiles(char * filename, char * password, memfile * root)
{
    char *  buf ;
    char *  cur ;
    int     fd ;
    int     i ;
    struct stat fileinfo ;

    uint8_t nonce[NONCE_SZ];
    uint8_t key[KEY_SZ];

    uint64_t    u1, u2, u3 ;
    size_t      header_sz ;
    size_t      payload_sz ;
    char        fname[MAXNAMESZ];

    header_sz = MAGIC_SZ + 2 + NONCE_SZ + CANARI_SZ ;
    /* Find out file size in bytes */
    if (stat(filename, &fileinfo)!=0) {
        logger("no such file: %s", filename);
        return 1 ;
    }
    if (fileinfo.st_size < header_sz) {
        logger("not a container: ", filename);
        return -1 ;
    }
    /* Map input file */
    if ((fd=open(filename, O_RDONLY))==-1) {
        logger("cannot open: %s", filename);
        return -1 ;
    }
    buf = (char*)mmap(0,
                      fileinfo.st_size,
                      PROT_READ | PROT_WRITE,
                      MAP_PRIVATE,
                      fd,
                      0);
    close(fd);
    if (buf==(char*)-1) {
        logger("cannot map: %s", filename);
        return -1;
    }
    cur = buf ;
    payload_sz = fileinfo.st_size - header_sz ;
    /*
     * A container header is composed of:
     * A magic number of MAGIC_SZ bytes
     * A version number on 2 bytes: major.minor
     * A nonce of size NONCE_SZ bytes
     * A canari of size CANARI_SZ bytes
     */
    /* Check magic number */
    for (i=0 ; i<MAGIC_SZ ; i++) {
        if (cur[i]!=mefs_magic[i]) {
            logger("not a container: ", filename);
            munmap(buf, fileinfo.st_size);
            return -1 ;
        }
    }
    cur += MAGIC_SZ ;
    /* Read version number */
    if (cur[0]!=mefs_version[0] ||
        cur[1]!=mefs_version[1]) {
        logger("unsupported version for: ", filename);
        munmap(buf, fileinfo.st_size);
        return -1 ;
    }
    cur+=2 ;

    /* Copy nonce for later use */
    memcpy(nonce, cur, NONCE_SZ);
    cur += NONCE_SZ ;
    /* Derive key from password */
    derive_key(password,
               strlen(password),
               nonce,
               NONCE_SZ,
               key,
               KEY_SZ,
               20000);
    /* Decrypt everything starting from CANARI, using nonce and key */
    stream_cipher(cur,
                  fileinfo.st_size-(MAGIC_SZ+2+NONCE_SZ),
                  0,
                  key,
                  nonce);
    /* Test canari has expected pattern: 0xaaaa...aa */
    for (i=0 ; i<CANARI_SZ ; i++) {
        if ((unsigned char)cur[i]!=0xaa) {
            logger("wrong password for container: %s", filename);
            munmap(buf, fileinfo.st_size);
            return -2 ;
        }
    }
    cur+=CANARI_SZ ;

    /* Read files one by one */
    /*
     * filename is a zero-padded string of size MAXNAMESZ
     * filesize on a 64 big-endian unsigned int
     * ctime    on a 64-big-endian unsigned int
     * mtime    on a 64-big-endian unsigned int
     */
    i=0 ;
    while (1) {
        memcpy(fname, cur, MAXNAMESZ);
        cur+=MAXNAMESZ;
        memcpy(&u1, cur, sizeof(uint64_t));
        cur+=sizeof(uint64_t);
        memcpy(&u2, cur, sizeof(uint64_t));
        cur+=sizeof(uint64_t);
        memcpy(&u3, cur, sizeof(uint64_t));
        cur+=sizeof(uint64_t);

        root[i].name = strdup(fname);
        root[i].sta.st_ino = inode_next();
        root[i].sta.st_size     = u1 ;
        root[i].sta.st_ctime    = u2 ;
        root[i].sta.st_mtime    = u3 ;

        root[i].data = malloc(u1);
        memcpy(root[i].data, cur, u1);
        cur+=u1 ;
        if ((cur-buf) >= fileinfo.st_size)
            break ;
        i++ ;
    }
    munmap(buf, fileinfo.st_size);
    return 0 ;
}
Esempio n. 2
0
std::map<std::string, double>
algorithm_benchmark(const std::string& name,
                    u32bit milliseconds,
                    Timer& timer,
                    RandomNumberGenerator& rng,
                    Algorithm_Factory& af)
   {
   std::vector<std::string> providers = af.providers_of(name);
   std::map<std::string, double> all_results;

   if(providers.empty()) // no providers, nothing to do
      return all_results;

   const u64bit ns_per_provider =
      ((u64bit)milliseconds * 1000 * 1000) / providers.size();

   std::vector<byte> buf(16 * 1024);
   rng.randomize(&buf[0], buf.size());

   for(u32bit i = 0; i != providers.size(); ++i)
      {
      const std::string provider = providers[i];

      std::pair<u64bit, u64bit> results(0, 0);

      if(const BlockCipher* proto =
            af.prototype_block_cipher(name, provider))
         {
         std::auto_ptr<BlockCipher> block_cipher(proto->clone());
         results = bench_block_cipher(block_cipher.get(), timer,
                                      ns_per_provider,
                                      &buf[0], buf.size());
         }
      else if(const StreamCipher* proto =
                 af.prototype_stream_cipher(name, provider))
         {
         std::auto_ptr<StreamCipher> stream_cipher(proto->clone());
         results = bench_stream_cipher(stream_cipher.get(), timer,
                                       ns_per_provider,
                                       &buf[0], buf.size());
         }
      else if(const HashFunction* proto =
                 af.prototype_hash_function(name, provider))
         {
         std::auto_ptr<HashFunction> hash(proto->clone());
         results = bench_hash(hash.get(), timer, ns_per_provider,
                              &buf[0], buf.size());
         }
      else if(const MessageAuthenticationCode* proto =
                 af.prototype_mac(name, provider))
         {
         std::auto_ptr<MessageAuthenticationCode> mac(proto->clone());
         results = bench_mac(mac.get(), timer, ns_per_provider,
                             &buf[0], buf.size());
         }

      if(results.first && results.second)
         {
         /* 953.67 == 1000 * 1000 * 1000 / 1024 / 1024 - the conversion
            factor from bytes per nanosecond to mebibytes per second.
         */
         double speed = (953.67 * results.first) / results.second;
         all_results[provider] = speed;
         }
      }

   return all_results;
   }
Esempio n. 3
0
/*
 * Save all files in rootdir to a container
 */
int memfile_savefiles(char * filename, char * password, memfile * root)
{
    FILE *  f ;
    int     i ;

    uint8_t nonce[NONCE_SZ];
    uint8_t key[KEY_SZ];
    uint8_t canari[CANARI_SZ];
    char    enc_name[MAXNAMESZ];
    uint64_t    u1, u2, u3 ;

    size_t  offset=0 ;

    /* Generate nonce */
    memcpy(nonce, get_nonce(), NONCE_SZ);
    /* Derive key from password */
    derive_key(password,
               strlen(password),
               nonce,
               NONCE_SZ,
               key,
               KEY_SZ,
               20000);
    /*
     * A container header is composed of:
     * A magic number of MAGIC_SZ bytes
     * A version number on 2 bytes: major.minor
     * A nonce of size NONCE_SZ bytes
     * A canari of size CANARI_SZ bytes
     */
    if ((f=fopen(filename, "w"))==NULL) {
        return 0 ;
    }
    /* Write magic number */
    fwrite(mefs_magic, 1, MAGIC_SZ, f);
    /* Write version */
    fwrite(mefs_version, 1, 2, f);
    /* Write nonce */
    fwrite(nonce, 1, NONCE_SZ, f);
    /* Generate and encrypt canari */
    for (i=0 ; i<CANARI_SZ ; i++) {
        canari[i] = 0xaa ;
    }
    stream_cipher(canari, CANARI_SZ, 0, key, nonce);
    fwrite(canari, 1, CANARI_SZ, f);
    offset += CANARI_SZ ;

    /* Write files one by one */
    /*
     * filename is a zero-padded string of size MAXNAMESZ
     * filesize on a 64 big-endian unsigned int
     * ctime    on a 64-big-endian unsigned int
     * mtime    on a 64-big-endian unsigned int
     */
    for (i=0 ; i<MAXFILES ; i++) {
        if (root[i].name==NULL) {
            continue ;
        }
        memset(enc_name, 0, MAXNAMESZ);
        strncpy(enc_name, root[i].name, MAXNAMESZ);
        stream_cipher(enc_name, MAXNAMESZ, offset, key, nonce);
        offset += MAXNAMESZ ;
        fwrite(enc_name, 1, MAXNAMESZ,  f);

        u1 = root[i].sta.st_size ;
        u2 = root[i].sta.st_ctime ;
        u3 = root[i].sta.st_mtime ;

        stream_cipher((uint8_t*)&u1, sizeof(uint64_t), offset, key, nonce);
        offset += sizeof(uint64_t);
        fwrite(&u1, sizeof(uint64_t), 1, f);

        stream_cipher((uint8_t*)&u2, sizeof(uint64_t), offset, key, nonce);
        offset += sizeof(uint64_t);
        fwrite(&u2, sizeof(uint64_t), 1, f);

        stream_cipher((uint8_t*)&u3, sizeof(uint64_t), offset, key, nonce);
        offset += sizeof(uint64_t);
        fwrite(&u3, sizeof(uint64_t), 1, f);

        stream_cipher(root[i].data,
                      root[i].sta.st_size, 
                      offset,
                      key,
                      nonce);
        offset += root[i].sta.st_size ;
        fwrite(root[i].data, 1, root[i].sta.st_size, f);
    }
    fclose(f);
    return 0 ;
}