
/*

  Fonctions de protection des logiciels Cryonetworks,
  utilisables par l'install

  juin 01 - Sylvain Huet

*/
extern "C" {
#include "./include/vscol.h"
}
#ifdef SERVER
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
extern "C"
{
#include"bignum.h"
}
#include"rsa.h"

/* -----------------------------------------

  TRAITEMENT DU KEYCODE

---------------------------------------- */

/* nombre magique que l'on retrouve dans le keycode */
#define MAGIC 0xfedcb

/* le keycode en clair contient dans cet ordre (à partir du bit 0) :
-	debut (4 bits) : date de début (en années à partir du 01/01/2000). 0 pour une version sans date de début spécifié (c'est le cas le plus courant)
-	id (32 bits) : identifiant unique du keycode (permet de différencier des keycodes équivalents)
-	magic (20 bits) : un magic number "fedcb"
-	param (16 bits) : paramètres divers
-	periode (6 bits) : la période de validité (en dizaines de jours). 0 pour une période illimitée
pour un total de 78 bits
*/

/* fonction de récupération du keycode en clair :
 - s_keycode et s_clef_publique sont des chaines codant un bignum en hexadécimal
 - b_res est un pointeur vers un bignum dans lequel on place le résultat
 La fonction effectue le calcul (keycode*keycode*keycode) modulo clef_publique
*/
int convertKeycod(char *s_keycode, char *s_clef_publique, short *b_res)
{
	short source[SIZEV];
	short k_pub[SIZEV];

	CRfromAsc(s_keycode,source);
	CRfromAsc(s_clef_publique,k_pub);
	CRmuln(source,source,k_pub,b_res);
	CRmuln(source,b_res,k_pub,b_res);
//	printf("tmp %04x %04x %04x %04x %04x\n",b_res[4],b_res[3],b_res[2],b_res[1],b_res[0]);
	return 0;
}


/* retourne la periode codée dans le keycode
   et la convertit en jours (après avoir vérifié magic)
- s_keycode est une chaîne hexadécimale contenant le keycode
- s_clef_publique est une chaîne hexadécimale contenant la clef publique
retourne -1 si mauvais keycode

détail interne :
- periode fait 6 bits à partir du bit 72
	- 6 bits à partir du bit 8 du 5eme short
- magic fait 20 bits à partir du bit 36 
	- 12 bits forts du 3eme short
	- puis 8 bits faibles du 4eme short
*/
int getPeriodeFromKeycode(char *s_keycode, char *s_clef_publique)
{
	short key[SIZEV];
	int magic_number;
	int periode;

	convertKeycod(s_keycode,s_clef_publique,key);

	magic_number=((key[2]>>4)&0xfff)+((key[3]&0xff)<<12);
	if (magic_number!=MAGIC) return -1;	// Mauvais Magic number

	periode=((key[4]>>8)&0x3f);

	return periode*10;	// conversion en jours
}

/* retourne la date codée dans le keycode
   et la convertit en jours depuis 01/01/2000 (après avoir vérifié magic)
- s_keycode est une chaîne hexadécimale contenant le keycode
- s_clef_publique est une chaîne hexadécimale contenant la clef publique
retourne -1 si mauvais keycode

détail interne :
- date fait 4 bits à partir du bit 0
	- 4 bits à partir du bit 0 du 1er short
- magic fait 20 bits à partir du bit 36 
	- 12 bits forts du 3eme short
	- puis 8 bits faibles du 4eme short
*/
int getDateFromKeycode(char *s_keycode, char *s_clef_publique)
{
	short key[SIZEV];
	int magic_number;
	int date;

	convertKeycod(s_keycode,s_clef_publique,key);

	magic_number=((key[2]>>4)&0xfff)+((key[3]&0xff)<<12);
	if (magic_number!=MAGIC) return -1;	// Mauvais Magic number

	date=key[0]&0xf;

	return date*365;	// conversion en jours
}

/* retourne le paramètre codé dans le keycode (après avoir vérifié magic)
- s_keycode est une chaîne hexadécimale contenant le keycode
- s_clef_publique est une chaîne hexadécimale contenant la clef publique
retourne -1 si mauvais keycode

détail interne :
- param fait 16 bits à partir du bit 56
	- 8 bits à partir du bit 8 du 4ème short
	- 8 bits à partir du bit 0 du 5ème short
- magic fait 20 bits à partir du bit 36 
	- 12 bits forts du 3eme short
	- puis 8 bits faibles du 4eme short
*/
int getParamFromKeycode(char *s_keycode, char *s_clef_publique)
{
	short key[SIZEV];
	int magic_number;
	int param;

	convertKeycod(s_keycode,s_clef_publique,key);

	magic_number=((key[2]>>4)&0xfff)+((key[3]&0xff)<<12);
	if (magic_number!=MAGIC) return -1;	// Mauvais Magic number

	param=((key[3]>>8)&0xff)+((key[4]&0xff)<<8);

	return param;
}

/* retourne l'identifiant codé dans le keycode (après avoir vérifié magic)
- s_keycode est une chaîne hexadécimale contenant le keycode
- s_clef_publique est une chaîne hexadécimale contenant la clef publique
retourne -1 si mauvais keycode

détail interne :
- id fait 32 bits à partir du bit 4
	- 12 bits à partir du bit 4 du 1er short
	- 16 bits du 2ème short
	- 4 bits à partir du bit 0 du 3ème short
- magic fait 20 bits à partir du bit 36 
	- 12 bits forts du 3eme short
	- puis 8 bits faibles du 4eme short
*/
int getIdFromKeycode(char *s_keycode, char *s_clef_publique)
{
	short key[SIZEV];
	int magic_number;
	int id;

	convertKeycod(s_keycode,s_clef_publique,key);

	magic_number=((key[2]>>4)&0xfff)+((key[3]&0xff)<<12);
	if (magic_number!=MAGIC) return -1;	// Mauvais Magic number

	id=((key[0]>>4)&0xfff)+((key[1]&0xffff)<<12)+((key[2]&0xf)<<28);

	return id;
}

#endif


