Changed SILC code to use new SRT and SCT APIs.
[silc.git] / lib / silcske / silcske.c
index a447123fcbbe3b00a31a2c384511697b4648b5b7..7331e23513c5c61d82c250bd35ab6bcb475b587d 100644 (file)
@@ -658,7 +658,6 @@ static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
     status = SILC_SKE_STATUS_ERROR;
 
   memset(string, 'F', l);
-  silc_free(string);
 
   return status;
 }
@@ -864,7 +863,7 @@ silc_ske_assemble_security_properties(SilcSKE ske,
   rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
 
   /* Get supported encryption algorithms */
-  rp->enc_alg_list = silc_cipher_get_supported();
+  rp->enc_alg_list = silc_cipher_get_supported(TRUE);
   rp->enc_alg_len = strlen(rp->enc_alg_list);
 
   /* Get supported hash algorithms */
@@ -1507,9 +1506,9 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase2)
 
     /* Sign the hash value */
     SILC_FSM_CALL(ske->key_op =
-                 silc_pkcs_sign(ske->private_key, hash, hash_len, FALSE,
-                                ske->prop->hash,
-                                silc_ske_initiator_sign_cb, ske));
+                 silc_pkcs_sign_async(ske->private_key, hash, hash_len, FALSE,
+                                      ske->prop->hash, ske->rng,
+                                      silc_ske_initiator_sign_cb, ske));
     /* NOT REACHED */
   }
 
@@ -1716,9 +1715,11 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase4)
 
     /* Verify signature */
     SILC_FSM_CALL(ske->key_op =
-                 silc_pkcs_verify(ske->prop->public_key, payload->sign_data,
-                                  payload->sign_len, hash, hash_len, NULL,
-                                  silc_ske_verify_cb, ske));
+                 silc_pkcs_verify_async(ske->prop->public_key,
+                                        payload->sign_data,
+                                        payload->sign_len, hash,
+                                        hash_len, FALSE, NULL,
+                                        silc_ske_verify_cb, ske));
     /* NOT REACHED */
   }
 
@@ -1882,7 +1883,8 @@ SILC_FSM_STATE(silc_ske_st_initiator_failure)
   SilcSKE ske = fsm_context;
   SilcUInt32 error = SILC_SKE_STATUS_ERROR;
 
-  if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
+  if (ske->packet && ske->packet->type == SILC_PACKET_FAILURE &&
+      silc_buffer_len(&ske->packet->buffer) == 4) {
     SILC_GET32_MSB(error, ske->packet->buffer.data);
     ske->status = error;
     silc_packet_free(ske->packet);
@@ -2245,11 +2247,11 @@ SILC_FSM_STATE(silc_ske_st_responder_phase4)
 
     /* Verify signature */
     SILC_FSM_CALL(ske->key_op =
-                 silc_pkcs_verify(ske->prop->public_key,
-                                  recv_payload->sign_data,
-                                  recv_payload->sign_len,
-                                  hash, hash_len, NULL,
-                                  silc_ske_verify_cb, ske));
+                 silc_pkcs_verify_async(ske->prop->public_key,
+                                        recv_payload->sign_data,
+                                        recv_payload->sign_len,
+                                        hash, hash_len, FALSE, NULL,
+                                        silc_ske_verify_cb, ske));
     /* NOT REACHED */
   }
 
@@ -2343,9 +2345,9 @@ SILC_FSM_STATE(silc_ske_st_responder_phase5)
 
     /* Sign the hash value */
     SILC_FSM_CALL(ske->key_op =
-                 silc_pkcs_sign(ske->private_key, hash, hash_len, FALSE,
-                                ske->prop->hash,
-                                silc_ske_responder_sign_cb, ske));
+                 silc_pkcs_sign_async(ske->private_key, hash, hash_len, FALSE,
+                                      ske->prop->hash, ske->rng,
+                                      silc_ske_responder_sign_cb, ske));
     /* NOT REACHED */
   }
 
@@ -2471,7 +2473,8 @@ SILC_FSM_STATE(silc_ske_st_responder_failure)
 
   SILC_LOG_DEBUG(("Key exchange protocol failed"));
 
-  if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
+  if (ske->packet && ske->packet->type == SILC_PACKET_FAILURE &&
+      silc_buffer_len(&ske->packet->buffer) == 4) {
     SILC_GET32_MSB(error, ske->packet->buffer.data);
     ske->status = error;
     silc_packet_free(ske->packet);
@@ -3390,7 +3393,7 @@ SilcBool silc_ske_set_keys(SilcSKE ske,
                           SilcHmac *ret_hmac_receive,
                           SilcHash *ret_hash)
 {
-  unsigned char iv[32];
+  unsigned char iv[SILC_HASH_MAXLEN];
   SilcBool iv_included = (prop->flags & SILC_SKE_SP_FLAG_IV_INCLUDED);
 
   /* Allocate ciphers to be used in the communication */
@@ -3417,6 +3420,12 @@ SilcBool silc_ske_set_keys(SilcSKE ske,
       return FALSE;
   }
 
+  /* Allocate hash */
+  if (ret_hash) {
+    if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
+      return FALSE;
+  }
+
   /* Set key material */
   memset(iv, 0, sizeof(iv));
   if (ske->responder) {
@@ -3425,10 +3434,24 @@ SilcBool silc_ske_set_keys(SilcSKE ske,
                          keymat->enc_key_len, TRUE);
 
       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
-        memcpy(iv, ske->hash, 4);
-        memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
+       /* Counter mode */
+       if (!ske->rekeying) {
+         /* Set IV. */
+         memcpy(iv, ske->hash, 4);
+         if (!iv_included)
+           memcpy(iv + 4, keymat->receive_iv, 8);
+       } else {
+         /* Rekey, recompute the truncated hash value. */
+         silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
+         if (!iv_included)
+           memcpy(iv + 4, keymat->receive_iv, 8);
+         else
+           memset(iv + 4, 0, 12);
+       }
+
         silc_cipher_set_iv(*ret_send_key, iv);
       } else {
+       /* Other modes */
        silc_cipher_set_iv(*ret_send_key, keymat->receive_iv);
       }
     }
@@ -3437,10 +3460,24 @@ SilcBool silc_ske_set_keys(SilcSKE ske,
                          keymat->enc_key_len, FALSE);
 
       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
-        memcpy(iv, ske->hash, 4);
-        memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
+       /* Counter mode */
+       if (!ske->rekeying) {
+         /* Set IV. */
+         memcpy(iv, ske->hash, 4);
+         if (!iv_included)
+           memcpy(iv + 4, keymat->send_iv, 8);
+       } else {
+         /* Rekey, recompute the truncated hash value. */
+         silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
+         if (!iv_included)
+           memcpy(iv + 4, keymat->send_iv, 8);
+         else
+           memset(iv + 4, 0, 12);
+       }
+
         silc_cipher_set_iv(*ret_receive_key, iv);
       } else {
+       /* Other modes */
        silc_cipher_set_iv(*ret_receive_key, keymat->send_iv);
       }
     }
@@ -3456,10 +3493,24 @@ SilcBool silc_ske_set_keys(SilcSKE ske,
                          keymat->enc_key_len, TRUE);
 
       if (silc_cipher_get_mode(*ret_send_key) == SILC_CIPHER_MODE_CTR) {
-        memcpy(iv, ske->hash, 4);
-        memcpy(iv + 4, keymat->send_iv, iv_included ? 4 : 8);
+       /* Counter mode */
+       if (!ske->rekeying) {
+         /* Set IV. */
+         memcpy(iv, ske->hash, 4);
+         if (!iv_included)
+           memcpy(iv + 4, keymat->send_iv, 8);
+       } else {
+         /* Rekey, recompute the truncated hash value. */
+         silc_hash_make(prop->hash, keymat->send_iv, 8, iv);
+         if (!iv_included)
+           memcpy(iv + 4, keymat->send_iv, 8);
+         else
+           memset(iv + 4, 0, 12);
+       }
+
        silc_cipher_set_iv(*ret_send_key, iv);
       } else {
+       /* Other modes */
        silc_cipher_set_iv(*ret_send_key, keymat->send_iv);
       }
     }
@@ -3468,10 +3519,25 @@ SilcBool silc_ske_set_keys(SilcSKE ske,
                          keymat->enc_key_len, FALSE);
 
       if (silc_cipher_get_mode(*ret_receive_key) == SILC_CIPHER_MODE_CTR) {
-        memcpy(iv, ske->hash, 4);
-        memcpy(iv + 4, keymat->receive_iv, iv_included ? 4 : 8);
+       /* Counter mode */
+       if (!ske->rekeying) {
+         /* Set IV.  If IV Included flag was negotiated we only set the
+            truncated hash value. */
+         memcpy(iv, ske->hash, 4);
+         if (!iv_included)
+           memcpy(iv + 4, keymat->receive_iv, 8);
+       } else {
+         /* Rekey, recompute the truncated hash value. */
+         silc_hash_make(prop->hash, keymat->receive_iv, 8, iv);
+         if (!iv_included)
+           memcpy(iv + 4, keymat->receive_iv, 8);
+         else
+           memset(iv + 4, 0, 12);
+       }
+
        silc_cipher_set_iv(*ret_receive_key, iv);
       } else {
+       /* Other modes */
        silc_cipher_set_iv(*ret_receive_key, keymat->receive_iv);
       }
     }
@@ -3483,12 +3549,6 @@ SilcBool silc_ske_set_keys(SilcSKE ske,
                        keymat->hmac_key_len);
   }
 
-  /* Allocate hash */
-  if (ret_hash) {
-    if (!silc_hash_alloc(silc_hash_get_name(prop->hash), ret_hash))
-      return FALSE;
-  }
-
   return TRUE;
 }