1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* 2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Dropbear - a SSH2 server 3f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 4f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Copyright (c) 2002,2003 Matt Johnston 5f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * All rights reserved. 6f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 7f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy 8f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal 9f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * in the Software without restriction, including without limitation the rights 10f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is 12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * furnished to do so, subject to the following conditions: 13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The above copyright notice and this permission notice shall be included in 15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * all copies or substantial portions of the Software. 16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * SOFTWARE. */ 24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "includes.h" 26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "dbutil.h" 27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "bignum.h" 28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "dss.h" 29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "buffer.h" 30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "ssh.h" 31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "random.h" 32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Handle DSS (Digital Signature Standard), aka DSA (D.S. Algorithm), 34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * operations, such as key reading, signing, verification. Key generation 35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * is in gendss.c, since it isn't required in the server itself. 36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * See FIPS186 or the Handbook of Applied Cryptography for details of the 38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * algorithm */ 39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef DROPBEAR_DSS 41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Load a dss key from a buffer, initialising the values. 43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The key will have the same format as buf_put_dss_key. 44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * These should be freed with dss_key_free. 45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ 46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint buf_get_dss_pub_key(buffer* buf, dss_key *key) { 47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("enter buf_get_dss_pub_key")) 49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_assert(key != NULL); 50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project key->p = m_malloc(sizeof(mp_int)); 51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project key->q = m_malloc(sizeof(mp_int)); 52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project key->g = m_malloc(sizeof(mp_int)); 53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project key->y = m_malloc(sizeof(mp_int)); 54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_mp_init_multi(key->p, key->q, key->g, key->y, NULL); 55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project key->x = NULL; 56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_incrpos(buf, 4+SSH_SIGNKEY_DSS_LEN); /* int + "ssh-dss" */ 58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (buf_getmpint(buf, key->p) == DROPBEAR_FAILURE 59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project || buf_getmpint(buf, key->q) == DROPBEAR_FAILURE 60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project || buf_getmpint(buf, key->g) == DROPBEAR_FAILURE 61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project || buf_getmpint(buf, key->y) == DROPBEAR_FAILURE) { 62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("leave buf_get_dss_pub_key: failed reading mpints")) 63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return DROPBEAR_FAILURE; 64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_count_bits(key->p) < MIN_DSS_KEYLEN) { 67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_log(LOG_WARNING, "DSS key too short"); 68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("leave buf_get_dss_pub_key: short key")) 69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return DROPBEAR_FAILURE; 70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("leave buf_get_dss_pub_key: success")) 73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return DROPBEAR_SUCCESS; 74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Same as buf_get_dss_pub_key, but reads a private "x" key at the end. 77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Loads a private dss key from a buffer 78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ 79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint buf_get_dss_priv_key(buffer* buf, dss_key *key) { 80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int ret = DROPBEAR_FAILURE; 82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_assert(key != NULL); 84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ret = buf_get_dss_pub_key(buf, key); 86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (ret == DROPBEAR_FAILURE) { 87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return DROPBEAR_FAILURE; 88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project key->x = m_malloc(sizeof(mp_int)); 91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_mp_init(key->x); 92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ret = buf_getmpint(buf, key->x); 93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (ret == DROPBEAR_FAILURE) { 94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_free(key->x); 95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return ret; 98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Clear and free the memory used by a public or private key */ 102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid dss_key_free(dss_key *key) { 103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("enter dsa_key_free")) 105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (key == NULL) { 106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("enter dsa_key_free: key == NULL")) 107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return; 108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (key->p) { 110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project mp_clear(key->p); 111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_free(key->p); 112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 113f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (key->q) { 114f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project mp_clear(key->q); 115f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_free(key->q); 116f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 117f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (key->g) { 118f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project mp_clear(key->g); 119f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_free(key->g); 120f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 121f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (key->y) { 122f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project mp_clear(key->y); 123f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_free(key->y); 124f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 125f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (key->x) { 126f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project mp_clear(key->x); 127f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_free(key->x); 128f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 129f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_free(key); 130f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("leave dsa_key_free")) 131f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 132f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 133f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* put the dss public key into the buffer in the required format: 134f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 135f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * string "ssh-dss" 136f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * mpint p 137f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * mpint q 138f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * mpint g 139f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * mpint y 140f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */ 141f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid buf_put_dss_pub_key(buffer* buf, dss_key *key) { 142f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 143f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_assert(key != NULL); 144f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_putstring(buf, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN); 145f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_putmpint(buf, key->p); 146f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_putmpint(buf, key->q); 147f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_putmpint(buf, key->g); 148f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_putmpint(buf, key->y); 149f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 150f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 151f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 152f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Same as buf_put_dss_pub_key, but with the private "x" key appended */ 153f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid buf_put_dss_priv_key(buffer* buf, dss_key *key) { 154f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 155f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_assert(key != NULL); 156f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_put_dss_pub_key(buf, key); 157f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_putmpint(buf, key->x); 158f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 159f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 160f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 161f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef DROPBEAR_SIGNKEY_VERIFY 162f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Verify a DSS signature (in buf) made on data by the key given. 163f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */ 164f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectint buf_dss_verify(buffer* buf, dss_key *key, const unsigned char* data, 165f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned int len) { 166f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 167f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char msghash[SHA1_HASH_SIZE]; 168f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project hash_state hs; 169f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int ret = DROPBEAR_FAILURE; 170f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DEF_MP_INT(val1); 171f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DEF_MP_INT(val2); 172f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DEF_MP_INT(val3); 173f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DEF_MP_INT(val4); 174f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project char * string = NULL; 175f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int stringlen; 176f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 177f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("enter buf_dss_verify")) 178f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_assert(key != NULL); 179f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 180f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_mp_init_multi(&val1, &val2, &val3, &val4, NULL); 181f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 182f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* get blob, check length */ 183f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project string = buf_getstring(buf, &stringlen); 184f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (stringlen != 2*SHA1_HASH_SIZE) { 185f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto out; 186f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 187f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 188f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* hash the data */ 189f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha1_init(&hs); 190f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha1_process(&hs, data, len); 191f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha1_done(&hs, msghash); 192f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 193f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* create the signature - s' and r' are the received signatures in buf */ 194f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* w = (s')-1 mod q */ 195f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* let val1 = s' */ 196f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes_to_mp(&val1, &string[SHA1_HASH_SIZE], SHA1_HASH_SIZE); 197f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 198f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_cmp(&val1, key->q) != MP_LT) { 199f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("verify failed, s' >= q")) 200f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto out; 201f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 202f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* let val2 = w = (s')^-1 mod q*/ 203f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_invmod(&val1, key->q, &val2) != MP_OKAY) { 204f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto out; 205f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 206f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 207f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* u1 = ((SHA(M')w) mod q */ 208f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* let val1 = SHA(M') = msghash */ 209f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes_to_mp(&val1, msghash, SHA1_HASH_SIZE); 210f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 211f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* let val3 = u1 = ((SHA(M')w) mod q */ 212f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_mulmod(&val1, &val2, key->q, &val3) != MP_OKAY) { 213f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto out; 214f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 215f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 216f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* u2 = ((r')w) mod q */ 217f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* let val1 = r' */ 218f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes_to_mp(&val1, &string[0], SHA1_HASH_SIZE); 219f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_cmp(&val1, key->q) != MP_LT) { 220f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("verify failed, r' >= q")) 221f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto out; 222f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 223f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* let val4 = u2 = ((r')w) mod q */ 224f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_mulmod(&val1, &val2, key->q, &val4) != MP_OKAY) { 225f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto out; 226f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 227f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 228f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* v = (((g)^u1 (y)^u2) mod p) mod q */ 229f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* val2 = g^u1 mod p */ 230f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_exptmod(key->g, &val3, key->p, &val2) != MP_OKAY) { 231f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto out; 232f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 233f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* val3 = y^u2 mod p */ 234f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_exptmod(key->y, &val4, key->p, &val3) != MP_OKAY) { 235f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto out; 236f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 237f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* val4 = ((g)^u1 (y)^u2) mod p */ 238f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_mulmod(&val2, &val3, key->p, &val4) != MP_OKAY) { 239f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto out; 240f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 241f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* val2 = v = (((g)^u1 (y)^u2) mod p) mod q */ 242f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_mod(&val4, key->q, &val2) != MP_OKAY) { 243f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project goto out; 244f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 245f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 246f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* check whether signatures verify */ 247f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_cmp(&val2, &val1) == MP_EQ) { 248f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* good sig */ 249f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ret = DROPBEAR_SUCCESS; 250f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 251f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 252f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectout: 253f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project mp_clear_multi(&val1, &val2, &val3, &val4, NULL); 254f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_free(string); 255f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 256f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return ret; 257f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 258f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 259f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* DROPBEAR_SIGNKEY_VERIFY */ 260f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 261f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef DSS_PROTOK 262f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* convert an unsigned mp into an array of bytes, malloced. 263f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * This array must be freed after use, len contains the length of the array, 264f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * if len != NULL */ 265f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic unsigned char* mptobytes(mp_int *mp, int *len) { 266f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 267f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char* ret; 268f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project int size; 269f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 270f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project size = mp_unsigned_bin_size(mp); 271f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project ret = m_malloc(size); 272f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_to_unsigned_bin(mp, ret) != MP_OKAY) { 273f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_exit("mem alloc error"); 274f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 275f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (len != NULL) { 276f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *len = size; 277f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 278f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project return ret; 279f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 280f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 281f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 282f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Sign the data presented with key, writing the signature contents 283f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * to the buffer 284f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 285f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * When DSS_PROTOK is #defined: 286f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The alternate k generation method is based on the method used in PuTTY. 287f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * In particular to avoid being vulnerable to attacks using flaws in random 288f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * generation of k, we use the following: 289f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 290f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * proto_k = SHA512 ( SHA512(x) || SHA160(message) ) 291f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * k = proto_k mod q 292f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * 293f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Now we aren't relying on the random number generation to protect the private 294f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * key x, which is a long term secret */ 295f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid buf_put_dss_sign(buffer* buf, dss_key *key, const unsigned char* data, 296f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned int len) { 297f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 298f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char msghash[SHA1_HASH_SIZE]; 299f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned int writelen; 300f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned int i; 301f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef DSS_PROTOK 302f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char privkeyhash[SHA512_HASH_SIZE]; 303f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char *privkeytmp; 304f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project unsigned char proto_k[SHA512_HASH_SIZE]; 305f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DEF_MP_INT(dss_protok); 306f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 307f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DEF_MP_INT(dss_k); 308f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DEF_MP_INT(dss_m); 309f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DEF_MP_INT(dss_temp1); 310f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DEF_MP_INT(dss_temp2); 311f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DEF_MP_INT(dss_r); 312f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project DEF_MP_INT(dss_s); 313f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project hash_state hs; 314f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 315f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("enter buf_put_dss_sign")) 316f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_assert(key != NULL); 317f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 318f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* hash the data */ 319f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha1_init(&hs); 320f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha1_process(&hs, data, len); 321f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha1_done(&hs, msghash); 322f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 323f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_mp_init_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s, 324f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &dss_m, NULL); 325f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifdef DSS_PROTOK 326f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* hash the privkey */ 327f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project privkeytmp = mptobytes(key->x, &i); 328f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha512_init(&hs); 329f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha512_process(&hs, "the quick brown fox jumped over the lazy dog", 44); 330f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha512_process(&hs, privkeytmp, i); 331f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha512_done(&hs, privkeyhash); 332f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_burn(privkeytmp, i); 333f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_free(privkeytmp); 334f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 335f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* calculate proto_k */ 336f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha512_init(&hs); 337f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha512_process(&hs, privkeyhash, SHA512_HASH_SIZE); 338f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha512_process(&hs, msghash, SHA1_HASH_SIZE); 339f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project sha512_done(&hs, proto_k); 340f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 341f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* generate k */ 342f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_mp_init(&dss_protok); 343f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes_to_mp(&dss_protok, proto_k, SHA512_HASH_SIZE); 344f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_mod(&dss_protok, key->q, &dss_k) != MP_OKAY) { 345f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_exit("dss error"); 346f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 347f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project mp_clear(&dss_protok); 348f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project m_burn(proto_k, SHA512_HASH_SIZE); 349f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#else /* DSS_PROTOK not defined*/ 350f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project gen_random_mpint(key->q, &dss_k); 351f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif 352f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 353f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* now generate the actual signature */ 354f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project bytes_to_mp(&dss_m, msghash, SHA1_HASH_SIZE); 355f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 356f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* g^k mod p */ 357f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_exptmod(key->g, &dss_k, key->p, &dss_temp1) != MP_OKAY) { 358f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_exit("dss error"); 359f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 360f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* r = (g^k mod p) mod q */ 361f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_mod(&dss_temp1, key->q, &dss_r) != MP_OKAY) { 362f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_exit("dss error"); 363f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 364f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 365f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* x*r mod q */ 366f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_mulmod(&dss_r, key->x, key->q, &dss_temp1) != MP_OKAY) { 367f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_exit("dss error"); 368f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 369f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* (SHA1(M) + xr) mod q) */ 370f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_addmod(&dss_m, &dss_temp1, key->q, &dss_temp2) != MP_OKAY) { 371f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_exit("dss error"); 372f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 373f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 374f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* (k^-1) mod q */ 375f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_invmod(&dss_k, key->q, &dss_temp1) != MP_OKAY) { 376f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_exit("dss error"); 377f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 378f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 379f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* s = (k^-1(SHA1(M) + xr)) mod q */ 380f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_mulmod(&dss_temp1, &dss_temp2, key->q, &dss_s) != MP_OKAY) { 381f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_exit("dss error"); 382f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 383f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 384f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_putstring(buf, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN); 385f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_putint(buf, 2*SHA1_HASH_SIZE); 386f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 387f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project writelen = mp_unsigned_bin_size(&dss_r); 388f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_assert(writelen <= SHA1_HASH_SIZE); 389f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* need to pad to 160 bits with leading zeros */ 390f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; i < SHA1_HASH_SIZE - writelen; i++) { 391f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_putbyte(buf, 0); 392f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 393f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_to_unsigned_bin(&dss_r, buf_getwriteptr(buf, writelen)) 394f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project != MP_OKAY) { 395f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_exit("dss error"); 396f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 397f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project mp_clear(&dss_r); 398f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_incrwritepos(buf, writelen); 399f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 400f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project writelen = mp_unsigned_bin_size(&dss_s); 401f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_assert(writelen <= SHA1_HASH_SIZE); 402f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* need to pad to 160 bits with leading zeros */ 403f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project for (i = 0; i < SHA1_HASH_SIZE - writelen; i++) { 404f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_putbyte(buf, 0); 405f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 406f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project if (mp_to_unsigned_bin(&dss_s, buf_getwriteptr(buf, writelen)) 407f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project != MP_OKAY) { 408f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project dropbear_exit("dss error"); 409f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project } 410f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project mp_clear(&dss_s); 411f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project buf_incrwritepos(buf, writelen); 412f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 413f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project mp_clear_multi(&dss_k, &dss_temp1, &dss_temp2, &dss_r, &dss_s, 414f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project &dss_m, NULL); 415f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 416f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project /* create the signature to return */ 417f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 418f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project TRACE(("leave buf_put_dss_sign")) 419f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project} 420f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project 421f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif /* DROPBEAR_DSS */ 422