/** * @brief performs a basic error check and after everything has passed, passes the information onto server via sendall * after the execution of this function, we will have all of the keys that pass the operations inside predicates * @param table name of the table we want to query from * @param key a member address of the pointer for the string of keys * @param max_keys is the max number of keys storage query is supposed to return * @param conn a pointer to the connection status of the server * @return return 0 for success, -1 for failure */ int storage_query(const char *table, const char *predicates, char **keys, const int max_keys, void *conn){ // if we have not Connected, do not execute. Also raise the error if (didConnect != 1){ errno = ERR_CONNECTION_FAIL; return -1; } if (didAuthenticate != 1){ errno = ERR_NOT_AUTHENTICATED; return -1; } if (table == NULL || keys == NULL || predicates == NULL || conn == NULL ){ errno = ERR_INVALID_PARAM; return -1; } // parse the values to see if its correct if (tablecheck(table) == 1){ errno = ERR_INVALID_PARAM; return -1; } // Connection is really just a socket file descriptor. int sock = (int)conn; // Send some data. char buf[MAX_CMD_LEN]; memset(buf, 0, sizeof buf); snprintf(buf, sizeof buf, "QUERY %s %s\n", table, predicates); if (sendall(sock, buf, strlen(buf)) == 0 && recvline(sock, buf, sizeof buf) == 0) { if (strcmp("table_fail", buf)== 0){ errno = ERR_TABLE_NOT_FOUND; return -1; } else if (strcmp("invalid_param", buf)== 0){ errno = ERR_INVALID_PARAM; return -1; } int i = 0; char* output = NULL; char buf_copy[100]; //printf("Keys that match:%s..",buf); if(buf[0] == '\0') return 0; strncpy(buf_copy,buf,strlen(buf)); output = strtok(buf_copy, ","); while (output != NULL){ keys[i] = malloc((strlen(output)+1)); strcpy(keys[i],output); output = strtok(NULL, ","); i++; if(*output == '*') { keys[i] == NULL; break; } } return i; } }
/** * @brief performs a basic error check and after everything has passed, passes the information onto server via sendall * after the execution of this function, we will have set a key along with its values inside the database * @param table name of the table we want to set to * @param key name of the key we want to set * @param record is the struct holding the configuration parameters of everything inside the configuration file * @param conn a pointer to the connection status of the server * @return return 0 for success, -1 for failure */ int storage_set(const char *table, const char *key, struct storage_record *record, void *conn) { // if we have not Connected, do not execute. Also raise the error if (didConnect != 1){ errno = ERR_CONNECTION_FAIL; return -1; } if (didAuthenticate != 1){ errno = ERR_NOT_AUTHENTICATED; return -1; } if (table == NULL || key == NULL || conn == NULL ){ errno = ERR_INVALID_PARAM; return -1; } // parse the values to see if its correct if (tablecheck(table) == 1 || keycheck(key) == 1 ){ errno = ERR_INVALID_PARAM; return -1; } // Connection is really just a socket file descriptor. int sock = (int)conn; // Send some data. char buf[MAX_CMD_LEN]; memset(buf, 0, sizeof buf); if(record != NULL){ snprintf(buf, sizeof buf, "SET %s %s %s\n", table, key, record->value); } else if(record == NULL){ snprintf(buf,sizeof buf, "SET %s %s null\n", table, key); } if (sendall(sock, buf, strlen(buf)) == 0 && recvline(sock, buf, sizeof buf) == 0) { if (strcmp("table_fail", buf)== 0){ errno = ERR_TABLE_NOT_FOUND; return -1; } else if (strcmp("key_fail", buf)== 0){ errno = ERR_KEY_NOT_FOUND; return -1; } else if (strcmp("unknown", buf)== 0){ errno = ERR_UNKNOWN; return -1; } else if (strcmp("invalid_param", buf)== 0){ errno = ERR_INVALID_PARAM; return -1; } else { return 0; } } return -1; }
/* * DES decryption of input from FILE pointer `fp' using key `sKey' and * tables specified in file `tablefile'. */ void decrypt(const char* sKey, const char* tablefile, FILE* fp) { uint8_t buf[8]; /* block size is 64 bits */ memset(buf, 0, 8 * sizeof(uint8_t)); int keys[16][48]; /* represent each key bit as an integer */ for (int i = 0; i < 16; ++i) { memset(keys[i], 0, 48 * sizeof(int)); } int** table = tablecheck(tablefile); int* V = table[11]; int* PC1 = table[12]; int* PC2 = table[13]; keyschedule(sKey, V, PC1, PC2, keys); reverse(keys, 16); int m[64]; int res[64]; memset(m, 0, 64 * sizeof(int)); memset(res, 0, 64 * sizeof(int)); while (!feof(fp)) { memset(buf, 0, 8 * sizeof(uint8_t)); int nObj = 0; for (int i =0; i < 8; ++i) { nObj = fread(&buf[i], 1, 1, fp); if (nObj == 0) { if (i == 0) { return; } else { break; } } } unpack(buf, m); des(m, table, keys, res); pack(res, buf); fwrite(buf, 1, 8, stdout); } }
// Decrypts the input using AES-128 driven by tablefile in the ECB mode using key // as the decryption key (16-byte long and in hexstring format) void decrypt(char *key_chars, FILE *table, FILE *input) { unsigned char round_key[44][4] = { { 0 } }; unsigned char* init_key = (unsigned char*)calloc(1,16); unsigned char* cipher_block = (unsigned char*)calloc(1,16); unsigned char* plain_block = (unsigned char*)calloc(1,16); // Verify table if(!tablecheck(table)) { return; } // Check key length if(strlen(key_chars) != 32) { fprintf(stderr, "ERROR: key must consist of 32 characters, all hex values.\n"); return; } // Read raw key hexchars in and convert to bytes else { char temp_val[3]; for(int i=0; i<16; i++) { if(!is_hex_char(key_chars[i*2]) || !is_hex_char(key_chars[i*2+1])) { fprintf(stderr, "ERROR: all values in the polynomial must be hex values.\n"); return; } temp_val[0] = key_chars[i*2]; temp_val[1] = key_chars[i*2+1]; temp_val[2] = ' '; init_key[i] = strtol(temp_val, NULL, 16); } } // Perform key expansion and store result in round_key key_expansion(init_key, round_key, table); /* // Read first 16 bytes from input text if(fread(cipher_block, 1, 16, input) < 16) { fprintf(stderr, "ERROR: input file was less than 16 bytes long.\n"); return; }*/ // Encrypt everything from input in 16-byte block bool first = true; int size; while((size = fread(cipher_block, 1, 16, input))) { if((*cipher_block == '\n') && (size == 1)) continue; // Encrypt a single block using AES-128 decrypt_block(cipher_block, plain_block, round_key, table, first); // Print current cipher block values to output for(int i=0; i<16; i++) { printf("%c", plain_block[i]); } // Reset blocks for next iteration first = false; for(int i=0; i<16; i++) { plain_block[i] = 0x00; cipher_block[i] = 0x00; } } free(init_key); free(plain_block); free(cipher_block); // PSEUDO-CODE // - Same as AES-128 encrypt, except for a few minor changes: // - The S-box needs to be inverted before it can be used for substitution // - You use the inverse polynomial instead of the original for mix_columns // - During shift_rows, you shift each row to the right instead of the left // - The round keys are used in reverse order // - The order of core operations is also slightly different // - Inv Shift Columns // - Substitute Bytes (inverse S-box) // - Add Round Key // - Mix Columns (inverse polynomial) // EDIT: modified to decrypt entire input with AES-128. Prints state outputs to stderr on first block. }
// Main method of HW5, mostly taking user input and running the correct prog int main(int argc, char *argv[]) { // Look for correct command line arguments if(argc <= 1) { usage(); return 0; } else { if(strcmp(argv[1], "tablecheck") == 0) { // Tablecheck prog should be run FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(tablefile) { tablecheck(tablefile); fclose(tablefile); } else { usage("tablecheck"); } } else if(strcmp(argv[1], "encrypt") == 0) { // Encrypt prog should be run char *key = NULL; FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-k=", 3) == 0) { key = argv[i]+3; } else if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(key && tablefile) { if(argv[argc-1][0] != '-') { // Take input from file FILE* fin = NULL; fin = fopen(argv[argc-1], "r"); if(fin == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[argc-1]); return 0; } encrypt(key, tablefile, fin); fclose(fin); } else { // Take input from cmd line encrypt(key, tablefile, stdin); } fclose(tablefile); } else { usage("encrypt"); } } else if(strcmp(argv[1], "decrypt") == 0) { // Decrypt prog should be run char *key = NULL; FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-k=", 3) == 0) { key = argv[i]+3; } else if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(key && tablefile) { if(argv[argc-1][0] != '-') { // Take input from file FILE* fin = NULL; fin = fopen(argv[argc-1], "r"); if(fin == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[argc-1]); return 0; } decrypt(key, tablefile, fin); fclose(fin); } else { // Take input from cmd line decrypt(key, tablefile, stdin); } fclose(tablefile); } else { usage("decrypt"); } } else if(strcmp(argv[1], "encrypt3") == 0) { // Encrypt3 prog should be run char *key3 = NULL; FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-k=", 3) == 0) { key3 = argv[i]+3; } else if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(key3 && tablefile) { if(argv[argc-1][0] != '-') { // Take input from file FILE* fin = NULL; fin = fopen(argv[argc-1], "r"); if(fin == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[argc-1]); return 0; } encrypt3(key3, tablefile, fin); fclose(fin); } else { // Take input from cmd line encrypt3(key3, tablefile, stdin); } fclose(tablefile); } else { usage("encrypt3"); } } else if(strcmp(argv[1], "decrypt3") == 0) { // Decrypt3 prog should be run char *key3 = NULL; FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-k=", 3) == 0) { key3 = argv[i]+3; } else if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(key3 && tablefile) { if(argv[argc-1][0] != '-') { // Take input from file FILE* fin = NULL; fin = fopen(argv[argc-1], "r"); if(fin == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[argc-1]); return 0; } decrypt3(key3, tablefile, fin); fclose(fin); } else { // Take input from cmd line decrypt3(key3, tablefile, stdin); } fclose(tablefile); } else { usage("decrypt3"); } } else { // Failed input usage(); } } return 0; }
//! ofObject = true => returns list of objects this object depends on //! ofObject = false => returns list of objects that depend on this object void MetadataItem::getDependencies(std::vector<Dependency>& list, bool ofObject) { DatabasePtr d = getDatabase(); int mytype = -1; // map DBH type to RDB$DEPENDENT TYPE NodeType dep_types[] = { ntTable, ntView, ntTrigger, ntUnknown, ntUnknown, ntProcedure,ntUnknown, ntException,ntUnknown, ntUnknown, ntUnknown, ntUnknown, ntUnknown, ntUnknown, ntGenerator, ntFunction }; int type_count = sizeof(dep_types)/sizeof(NodeType); for (int i = 0; i < type_count; i++) if (typeM == dep_types[i]) mytype = i; // system tables should be treated as tables if (typeM == ntSysTable) mytype = 0; int mytype2 = mytype; // views count as relations(tables) when other object refer to them if (mytype == 1 && !ofObject) mytype2 = 0; if (typeM == ntUnknown || mytype == -1) throw FRError(_("Unsupported type")); IBPP::Database& db = d->getIBPPDatabase(); IBPP::Transaction tr1 = IBPP::TransactionFactory(db, IBPP::amRead); tr1->Start(); IBPP::Statement st1 = IBPP::StatementFactory(db, tr1); wxString o1 = (ofObject ? "DEPENDENT" : "DEPENDED_ON"); wxString o2 = (ofObject ? "DEPENDED_ON" : "DEPENDENT"); wxString sql = "select RDB$" + o2 + "_TYPE, RDB$" + o2 + "_NAME, RDB$FIELD_NAME \n " " from RDB$DEPENDENCIES \n " " where RDB$" + o1 + "_TYPE in (?,?) and RDB$" + o1 + "_NAME = ? \n "; int params = 1; if ((typeM == ntTable || typeM == ntSysTable || typeM == ntView) && ofObject) // get deps for computed columns { // view needed to bind with generators sql += " union \n" " SELECT DISTINCT d.rdb$depended_on_type, d.rdb$depended_on_name, d.rdb$field_name \n" " FROM rdb$relation_fields f \n" " LEFT JOIN rdb$dependencies d ON d.rdb$dependent_name = f.rdb$field_source \n" " WHERE d.rdb$dependent_type = 3 AND f.rdb$relation_name = ? \n"; params++; } if (!ofObject) // find tables that have calculated columns based on "this" object { sql += "union \n" " SELECT distinct cast(0 as smallint), f.rdb$relation_name, f.rdb$field_name \n" " from rdb$relation_fields f \n" " left join rdb$dependencies d on d.rdb$dependent_name = f.rdb$field_source \n" " where d.rdb$dependent_type = 3 and d.rdb$depended_on_name = ? "; params++; } // get the exact table and fields for views // rdb$dependencies covers deps. for WHERE clauses in SELECTs in VIEW body // but we also need mapping for column list in SELECT. These 2 queries cover it: if (ofObject && typeM == ntView) { sql += " union \n" " select distinct cast(0 as smallint), vr.RDB$RELATION_NAME, f.RDB$BASE_FIELD \n" " from RDB$RELATION_FIELDS f \n" " join RDB$VIEW_RELATIONS vr on f.RDB$VIEW_CONTEXT = vr.RDB$VIEW_CONTEXT \n" " and f.RDB$RELATION_NAME = vr.RDB$VIEW_NAME \n" " where f.rdb$relation_name = ? \n"; params++; } // views can depend on other views as well // we might need to add procedures here one day when Firebird gains support for it if (!ofObject && (typeM == ntView || typeM == ntTable || typeM == ntSysTable)) { sql += " union \n" " select distinct cast(0 as smallint), f.RDB$RELATION_NAME, f.RDB$BASE_FIELD \n" " from RDB$RELATION_FIELDS f \n" " join RDB$VIEW_RELATIONS vr on f.RDB$VIEW_CONTEXT = vr.RDB$VIEW_CONTEXT \n" " and f.RDB$RELATION_NAME = vr.RDB$VIEW_NAME \n" " where vr.rdb$relation_name = ? \n"; params++; } sql += " order by 1, 2, 3"; st1->Prepare(wx2std(sql, d->getCharsetConverter())); st1->Set(1, mytype); st1->Set(2, mytype2); for (int i = 0; i < params; i++) st1->Set(3 + i, wx2std(getName_(), d->getCharsetConverter())); st1->Execute(); MetadataItem* last = 0; Dependency* dep = 0; while (st1->Fetch()) { int object_type; st1->Get(1, &object_type); if (object_type > type_count) // some system object, not interesting for us continue; NodeType t = dep_types[object_type]; if (t == ntUnknown) // ditto continue; std::string objname_std; st1->Get(2, objname_std); wxString objname(std2wxIdentifier(objname_std, d->getCharsetConverter())); MetadataItem* current = d->findByNameAndType(t, objname); if (!current) { if (t == ntTable) { // maybe it's a view masked as table current = d->findByNameAndType(ntView, objname); // or possibly a system table if (!current) current = d->findByNameAndType(ntSysTable, objname); } if (!ofObject && t == ntTrigger) { // system trigger dependent of this object indicates possible check constraint on a table // that references this object. So, let's check if this trigger is used for check constraint // and get that table's name IBPP::Statement st2 = IBPP::StatementFactory(db, tr1); st2->Prepare( "select r.rdb$relation_name from rdb$relation_constraints r " " join rdb$check_constraints c on r.rdb$constraint_name=c.rdb$constraint_name " " and r.rdb$constraint_type = 'CHECK' where c.rdb$trigger_name = ? " ); st2->Set(1, objname_std); st2->Execute(); if (st2->Fetch()) // table using that trigger found { std::string s; st2->Get(1, s); wxString tablecheck(std2wxIdentifier(s, d->getCharsetConverter())); if (getName_() != tablecheck) // avoid self-reference current = d->findByNameAndType(ntTable, tablecheck); } } if (!current) continue; } if (current != last) // new object { Dependency de(current); list.push_back(de); dep = &list.back(); last = current; } if (!st1->IsNull(3)) { std::string s; st1->Get(3, s); dep->addField(std2wxIdentifier(s, d->getCharsetConverter())); } } // TODO: perhaps this could be moved to Table? // call MetadataItem::getDependencies() and then add this if ((typeM == ntTable || typeM == ntSysTable) && ofObject) // foreign keys of this table + computed columns { Table *t = dynamic_cast<Table *>(this); std::vector<ForeignKey> *f = t->getForeignKeys(); for (std::vector<ForeignKey>::const_iterator it = f->begin(); it != f->end(); ++it) { MetadataItem *table = d->findByNameAndType(ntTable, (*it).getReferencedTable()); if (!table) { throw FRError(wxString::Format(_("Table %s not found."), (*it).getReferencedTable().c_str())); } Dependency de(table); de.setFields((*it).getReferencedColumns()); list.push_back(de); } // Add check constraints here (CHECKS are checked via system triggers), example: // table1::check( table1.field1 > select max(field2) from table2 ) // So, table vs any object from this ^^^ select // Algorithm: 1.find all system triggers bound to that CHECK constraint // 2.find dependencies for those system triggers // 3.display those dependencies as deps. of this table st1->Prepare("select distinct c.rdb$trigger_name from rdb$relation_constraints r " " join rdb$check_constraints c on r.rdb$constraint_name=c.rdb$constraint_name " " and r.rdb$constraint_type = 'CHECK' where r.rdb$relation_name= ? " ); st1->Set(1, wx2std(getName_(), d->getCharsetConverter())); st1->Execute(); std::vector<Dependency> tempdep; while (st1->Fetch()) { std::string s; st1->Get(1, s); Trigger t(d->shared_from_this(), std2wxIdentifier(s, d->getCharsetConverter())); t.getDependencies(tempdep, true); } // remove duplicates, and self-references from "tempdep" while (true) { std::vector<Dependency>::iterator to_remove = tempdep.end(); for (std::vector<Dependency>::iterator it = tempdep.begin(); it != tempdep.end(); ++it) { if ((*it).getDependentObject() == this) { to_remove = it; break; } to_remove = std::find(it + 1, tempdep.end(), (*it)); if (to_remove != tempdep.end()) break; } if (to_remove == tempdep.end()) break; else tempdep.erase(to_remove); } list.insert(list.end(), tempdep.begin(), tempdep.end()); } // TODO: perhaps this could be moved to Table? if ((typeM == ntTable || typeM == ntSysTable) && !ofObject) // foreign keys of other tables { st1->Prepare( "select r1.rdb$relation_name, i.rdb$field_name " " from rdb$relation_constraints r1 " " join rdb$ref_constraints c on r1.rdb$constraint_name = c.rdb$constraint_name " " join rdb$relation_constraints r2 on c.RDB$CONST_NAME_UQ = r2.rdb$constraint_name " " join rdb$index_segments i on r1.rdb$index_name=i.rdb$index_name " " where r2.rdb$relation_name=? " " and r1.rdb$constraint_type='FOREIGN KEY' " ); st1->Set(1, wx2std(getName_(), d->getCharsetConverter())); st1->Execute(); wxString lasttable; Dependency* dep = 0; while (st1->Fetch()) { std::string s; st1->Get(1, s); wxString table_name(std2wxIdentifier(s, d->getCharsetConverter())); st1->Get(2, s); wxString field_name(std2wxIdentifier(s, d->getCharsetConverter())); if (table_name != lasttable) // new { MetadataItem* table = d->findByNameAndType(ntTable, table_name); if (!table) continue; // dummy check Dependency de(table); list.push_back(de); dep = &list.back(); lasttable = table_name; } dep->addField(field_name); } } tr1->Commit(); }
// Main method of HW6, mostly taking user input and running the correct prog int main(int argc, char *argv[]) { // Look for correct command line arguments if(argc <= 1) { usage(); return 0; } else { if(strcmp(argv[1], "tablecheck") == 0) { // Tablecheck prog should be run FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(tablefile) { tablecheck(tablefile); fclose(tablefile); } else { usage("tablecheck"); } } else if(strcmp(argv[1], "modprod") == 0) { // Modprod prog should be run char *poly1 = NULL; char *poly2 = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-p1=", 4) == 0) { poly1 = argv[i]+4; } else if(strncmp(argv[i], "-p2=", 4) == 0) { poly2 = argv[i]+4; } } if(poly1 && poly2) { modprod(poly1, poly2); } else { usage("modprod"); } } else if(strcmp(argv[1], "keyexpand") == 0) { // Keyexpand prog should be run char *key = NULL; FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-k=", 3) == 0) { key = argv[i]+3; } else if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(key && tablefile) { keyexpand(key, tablefile); fclose(tablefile); } else { usage("keyexpand"); } } else if(strcmp(argv[1], "encrypt") == 0) { // Encrypt prog should be run char *key = NULL; FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-k=", 3) == 0) { key = argv[i]+3; } else if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(key && tablefile) { if(argv[argc-1][0] != '-') { // Take input from file FILE* fin = NULL; fin = fopen(argv[argc-1], "r"); if(fin == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[argc-1]); return 0; } encrypt(key, tablefile, fin); fclose(fin); } else { // Take input from cmd line encrypt(key, tablefile, stdin); } fclose(tablefile); } else { usage("encrypt"); } } else if(strcmp(argv[1], "decrypt") == 0) { // Decrypt prog should be run char *key = NULL; FILE* tablefile = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-k=", 3) == 0) { key = argv[i]+3; } else if(strncmp(argv[i], "-t=", 3) == 0) { tablefile = fopen(argv[i]+3, "r"); if(tablefile == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[i]+3); return 0; } } } if(key && tablefile) { if(argv[argc-1][0] != '-') { // Take input from file FILE* fin = NULL; fin = fopen(argv[argc-1], "r"); if(fin == NULL) { fprintf(stderr, "ERROR: invalid file '%s' for reading.\n", argv[argc-1]); return 0; } decrypt(key, tablefile, fin); fclose(fin); } else { // Take input from cmd line decrypt(key, tablefile, stdin); } fclose(tablefile); } else { usage("decrypt"); } } else if(strcmp(argv[1], "inverse") == 0) { // Inverse prog should be run char *poly = NULL; for(int i=2; i<argc; i++) { if(strncmp(argv[i], "-p=", 3) == 0) { poly = argv[i]+3; } } if(poly) { inverse(poly); } else { usage("inverse"); } } else { // Failed input usage(); } } return 0; }
void encrypt3(char *s,FILE* f,FILE* p,int decrypt){ char PC1[56]={0}; char PC2[48]={0}; unsigned char input[8]={0}; char V[16]={0}; int K1[16][48],K2[16][48],K3[16][48]; char IP[64]={0}; char IP1[64]={0}; unsigned int m[64]={0}; int L0[32]={0},R0[32]={0}; int i=0,j,k,temp,c,r; char E[48]={0}; char S[8][64]; char P[32]; int Rtemp[48]={0}; char T[32]={0}; char fun[32]={0}; int output[64]={0}; int outtemp[64]={0}; int cc; int flag=0; int count=0; //fseek(f,0,SEEK_SET); if(tablecheck(f,PC1,V,PC2,IP,E,S,P)==false){ fprintf(stderr,"malformed table\n"); return ; } if(s[0]!='1'){ fprintf(stderr,"key too short\n"); return ; } key_schedule(s,PC1,V,PC2,K1); key_schedule(s+16,PC1,V,PC2,K2); key_schedule(s+32,PC1,V,PC2,K3); while((cc=fgetc(p))!=EOF){ input[count]=cc; count++; if (count==8) { array_hex_to_bin(input,m,8,0); for(i=0;i<32;i++){ L0[i]=m[IP[i]-1];// IP (m1m2...m64) } for(i=32;i<64;i++){ R0[i-32]=m[IP[i]-1]; } if (flag==0) { fprintf(stderr,"(L0,R0)="); print_hex_from_bin(L0,32); print_hex_from_bin(R0,32); fprintf(stderr,"\n"); } for(i=0;i<16;i++){ for(j=0;j<48;j++) { if(decrypt==0){ Rtemp[j]=(R0[E[j]-1]+K1[i][j])%2;// E(Ri-1)+ki }else{ Rtemp[j]=(R0[E[j]-1]+K3[15-i][j])%2; } } for(j=0;j<8;j++){ r=Rtemp[j*6]*2+Rtemp[j*6+5];//r and c c=0; temp=8; for(k=1;k<5;k++){ c+=Rtemp[j*6+k]*temp; temp/=2; } temp=S[j][r*16+c];// Sbox T[j*4+3]=temp%2; temp/=2; T[j*4+2]=temp%2; temp/=2; T[j*4+1]=temp%2; temp/=2; T[j*4]=temp%2; } for(j=0;j<32;j++){ fun[j]=T[P[j]-1];//P permutation } for(j=0;j<32;j++){ Rtemp[j]=(L0[j]+fun[j])%2;//L0 + } if (flag==0) { fprintf(stderr,"(L%d,R%d)=",i+1,i+1); print_hex_from_bin(R0,32); print_hex_from_bin(Rtemp,32); fprintf(stderr,"\n"); } if(i!=15){ for(j=0;j<32;j++){ L0[j]=R0[j]; } for(j=0;j<32;j++){ R0[j]=Rtemp[j]; } } } inverse(IP,IP1); for(i=0;i<64;i++){ if(i<32) outtemp[i]=Rtemp[i]; else outtemp[i]=R0[i-32]; } for(i=0;i<64;i++){ output[i]=outtemp[IP1[i]-1]; } //---------------------------------------------------------------------------------------------- for(i=0;i<64;i++){ m[i]=output[i]; } for(i=0;i<32;i++){ L0[i]=m[IP[i]-1];// IP (m1m2...m64) } for(i=32;i<64;i++){ R0[i-32]=m[IP[i]-1]; } if (flag==0) { fprintf(stderr,"(L0,R0)="); print_hex_from_bin(L0,32); print_hex_from_bin(R0,32); fprintf(stderr,"\n"); } for(i=0;i<16;i++){ for(j=0;j<48;j++) { if(decrypt==1){ Rtemp[j]=(R0[E[j]-1]+K2[i][j])%2;// E(Ri-1)+ki }else{ Rtemp[j]=(R0[E[j]-1]+K2[15-i][j])%2; } } for(j=0;j<8;j++){ r=Rtemp[j*6]*2+Rtemp[j*6+5];//r and c c=0; temp=8; for(k=1;k<5;k++){ c+=Rtemp[j*6+k]*temp; temp/=2; } temp=S[j][r*16+c];// Sbox T[j*4+3]=temp%2; temp/=2; T[j*4+2]=temp%2; temp/=2; T[j*4+1]=temp%2; temp/=2; T[j*4]=temp%2; } for(j=0;j<32;j++){ fun[j]=T[P[j]-1];//P permutation } for(j=0;j<32;j++){ Rtemp[j]=(L0[j]+fun[j])%2;//L0 + } if (flag==0) { fprintf(stderr,"(L%d,R%d)=",i+1,i+1); print_hex_from_bin(R0,32); print_hex_from_bin(Rtemp,32); fprintf(stderr,"\n"); } if(i!=15){ for(j=0;j<32;j++){ L0[j]=R0[j]; } for(j=0;j<32;j++){ R0[j]=Rtemp[j]; } } } inverse(IP,IP1); for(i=0;i<64;i++){ if(i<32) outtemp[i]=Rtemp[i]; else outtemp[i]=R0[i-32]; } for(i=0;i<64;i++){ output[i]=outtemp[IP1[i]-1]; } //---------------------------------------------------------------------------------------------- for(i=0;i<64;i++){ m[i]=output[i]; } for(i=0;i<32;i++){ L0[i]=m[IP[i]-1];// IP (m1m2...m64) } for(i=32;i<64;i++){ R0[i-32]=m[IP[i]-1]; } if (flag==0) { fprintf(stderr,"(L0,R0)="); print_hex_from_bin(L0,32); print_hex_from_bin(R0,32); fprintf(stderr,"\n"); } for(i=0;i<16;i++){ for(j=0;j<48;j++) { if(decrypt==0){ Rtemp[j]=(R0[E[j]-1]+K3[i][j])%2;// E(Ri-1)+ki }else{ Rtemp[j]=(R0[E[j]-1]+K1[15-i][j])%2; } } for(j=0;j<8;j++){ r=Rtemp[j*6]*2+Rtemp[j*6+5];//r and c c=0; temp=8; for(k=1;k<5;k++){ c+=Rtemp[j*6+k]*temp; temp/=2; } temp=S[j][r*16+c];// Sbox T[j*4+3]=temp%2; temp/=2; T[j*4+2]=temp%2; temp/=2; T[j*4+1]=temp%2; temp/=2; T[j*4]=temp%2; } for(j=0;j<32;j++){ fun[j]=T[P[j]-1];//P permutation } for(j=0;j<32;j++){ Rtemp[j]=(L0[j]+fun[j])%2;//L0 + } if (flag==0) { fprintf(stderr,"(L%d,R%d)=",i+1,i+1); print_hex_from_bin(R0,32); print_hex_from_bin(Rtemp,32); fprintf(stderr,"\n"); } if(i!=15){ for(j=0;j<32;j++){ L0[j]=R0[j]; } for(j=0;j<32;j++){ R0[j]=Rtemp[j]; } } } inverse(IP,IP1); for(i=0;i<64;i++){ if(i<32) outtemp[i]=Rtemp[i]; else outtemp[i]=R0[i-32]; } for(i=0;i<64;i++){ output[i]=outtemp[IP1[i]-1]; } //---------------------------------------------------------------------------------------------- print_char_from_bin(output,64); flag=1; count=0; } } if(count>0){ array_hex_to_bin(input,m,count,8-count); for(i=0;i<32;i++){ L0[i]=m[IP[i]-1];// IP (m1m2...m64) } for(i=32;i<64;i++){ R0[i-32]=m[IP[i]-1]; } if (flag==0) { fprintf(stderr,"(L0,R0)="); print_hex_from_bin(L0,32); print_hex_from_bin(R0,32); fprintf(stderr,"\n"); } for(i=0;i<16;i++){ for(j=0;j<48;j++) { if(decrypt==0){ Rtemp[j]=(R0[E[j]-1]+K1[i][j])%2;// E(Ri-1)+ki }else{ Rtemp[j]=(R0[E[j]-1]+K3[15-i][j])%2; } } for(j=0;j<8;j++){ r=Rtemp[j*6]*2+Rtemp[j*6+5];//r and c c=0; temp=8; for(k=1;k<5;k++){ c+=Rtemp[j*6+k]*temp; temp/=2; } temp=S[j][r*16+c];// Sbox T[j*4+3]=temp%2; temp/=2; T[j*4+2]=temp%2; temp/=2; T[j*4+1]=temp%2; temp/=2; T[j*4]=temp%2; } for(j=0;j<32;j++){ fun[j]=T[P[j]-1];//P permutation } for(j=0;j<32;j++){ Rtemp[j]=(L0[j]+fun[j])%2;//L0 + } if (flag==0) { fprintf(stderr,"(L%d,R%d)=",i+1,i+1); print_hex_from_bin(R0,32); print_hex_from_bin(Rtemp,32); fprintf(stderr,"\n"); } if(i!=15){ for(j=0;j<32;j++){ L0[j]=R0[j]; } for(j=0;j<32;j++){ R0[j]=Rtemp[j]; } } } inverse(IP,IP1); for(i=0;i<64;i++){ if(i<32) outtemp[i]=Rtemp[i]; else outtemp[i]=R0[i-32]; } for(i=0;i<64;i++){ output[i]=outtemp[IP1[i]-1]; } //---------------------------------------------------------------------------------------------- for(i=0;i<64;i++){ m[i]=output[i]; } for(i=0;i<32;i++){ L0[i]=m[IP[i]-1];// IP (m1m2...m64) } for(i=32;i<64;i++){ R0[i-32]=m[IP[i]-1]; } if (flag==0) { fprintf(stderr,"(L0,R0)="); print_hex_from_bin(L0,32); print_hex_from_bin(R0,32); fprintf(stderr,"\n"); } for(i=0;i<16;i++){ for(j=0;j<48;j++) { if(decrypt==1){ Rtemp[j]=(R0[E[j]-1]+K2[i][j])%2;// E(Ri-1)+ki }else{ Rtemp[j]=(R0[E[j]-1]+K2[15-i][j])%2; } } for(j=0;j<8;j++){ r=Rtemp[j*6]*2+Rtemp[j*6+5];//r and c c=0; temp=8; for(k=1;k<5;k++){ c+=Rtemp[j*6+k]*temp; temp/=2; } temp=S[j][r*16+c];// Sbox T[j*4+3]=temp%2; temp/=2; T[j*4+2]=temp%2; temp/=2; T[j*4+1]=temp%2; temp/=2; T[j*4]=temp%2; } for(j=0;j<32;j++){ fun[j]=T[P[j]-1];//P permutation } for(j=0;j<32;j++){ Rtemp[j]=(L0[j]+fun[j])%2;//L0 + } if (flag==0) { fprintf(stderr,"(L%d,R%d)=",i+1,i+1); print_hex_from_bin(R0,32); print_hex_from_bin(Rtemp,32); fprintf(stderr,"\n"); } if(i!=15){ for(j=0;j<32;j++){ L0[j]=R0[j]; } for(j=0;j<32;j++){ R0[j]=Rtemp[j]; } } } inverse(IP,IP1); for(i=0;i<64;i++){ if(i<32) outtemp[i]=Rtemp[i]; else outtemp[i]=R0[i-32]; } for(i=0;i<64;i++){ output[i]=outtemp[IP1[i]-1]; } //---------------------------------------------------------------------------------------------- for(i=0;i<64;i++){ m[i]=output[i]; } for(i=0;i<32;i++){ L0[i]=m[IP[i]-1];// IP (m1m2...m64) } for(i=32;i<64;i++){ R0[i-32]=m[IP[i]-1]; } if (flag==0) { fprintf(stderr,"(L0,R0)="); print_hex_from_bin(L0,32); print_hex_from_bin(R0,32); fprintf(stderr,"\n"); } for(i=0;i<16;i++){ for(j=0;j<48;j++) { if(decrypt==0){ Rtemp[j]=(R0[E[j]-1]+K3[i][j])%2;// E(Ri-1)+ki }else{ Rtemp[j]=(R0[E[j]-1]+K1[15-i][j])%2; } } for(j=0;j<8;j++){ r=Rtemp[j*6]*2+Rtemp[j*6+5];//r and c c=0; temp=8; for(k=1;k<5;k++){ c+=Rtemp[j*6+k]*temp; temp/=2; } temp=S[j][r*16+c];// Sbox T[j*4+3]=temp%2; temp/=2; T[j*4+2]=temp%2; temp/=2; T[j*4+1]=temp%2; temp/=2; T[j*4]=temp%2; } for(j=0;j<32;j++){ fun[j]=T[P[j]-1];//P permutation } for(j=0;j<32;j++){ Rtemp[j]=(L0[j]+fun[j])%2;//L0 + } if (flag==0) { fprintf(stderr,"(L%d,R%d)=",i+1,i+1); print_hex_from_bin(R0,32); print_hex_from_bin(Rtemp,32); fprintf(stderr,"\n"); } if(i!=15){ for(j=0;j<32;j++){ L0[j]=R0[j]; } for(j=0;j<32;j++){ R0[j]=Rtemp[j]; } } } inverse(IP,IP1); for(i=0;i<64;i++){ if(i<32) outtemp[i]=Rtemp[i]; else outtemp[i]=R0[i-32]; } for(i=0;i<64;i++){ output[i]=outtemp[IP1[i]-1]; } //---------------------------------------------------------------------------------------------- print_char_from_bin(output,64); } return; }