// File: /workspace/github_c_makefile_star2_O3/liuhaotian[P]xmppsh/libstrophe/src/sasl.c
// Function: sasl_digest_md5
char *sasl_digest_md5(xmpp_ctx_t *ctx, const char *challenge,
			const char *jid, const char *password) {
    hash_t *table;
    char *result = NULL;
    char *node, *domain, *realm;
    char *value;
    char *response;
    int rlen;
    struct MD5Context MD5;
    unsigned char digest[16], HA1[16], HA2[16];
    char hex[32];

    /* our digest response is 
	Hex( KD( HEX(MD5(A1)),
	  nonce ':' nc ':' cnonce ':' qop ':' HEX(MD5(A2))
	))

       where KD(k, s) = MD5(k ':' s),
	A1 = MD5( node ':' realm ':' password ) ':' nonce ':' cnonce
	A2 = "AUTHENTICATE" ':' "xmpp/" domain

       If there is an authzid it is ':'-appended to A1 */

    /* parse the challenge */
    table = _parse_digest_challenge(ctx, challenge);
    if (table == NULL) {
	xmpp_error(ctx, "SASL", "couldn't parse digest challenge");
	return NULL;
    }

    node = xmpp_jid_node(ctx, jid);
    domain = xmpp_jid_domain(ctx, jid);

    /* generate default realm of domain if one didn't come from the
       server */
    realm = hash_get(table, "realm");
    if (realm == NULL || strlen(realm) == 0) {
	hash_add(table, "realm", xmpp_strdup(ctx, domain));
	realm = hash_get(table, "realm");
    }

    /* add our response fields */
    hash_add(table, "username", xmpp_strdup(ctx, node));
    /* TODO: generate a random cnonce */
    hash_add(table, "cnonce", xmpp_strdup(ctx, "00DEADBEEF00"));
    hash_add(table, "nc", xmpp_strdup(ctx, "00000001"));
    hash_add(table, "qop", xmpp_strdup(ctx, "auth"));
    value = xmpp_alloc(ctx, 5 + strlen(domain) + 1);
    memcpy(value, "xmpp/", 5);
    memcpy(value+5, domain, strlen(domain));
    value[5+strlen(domain)] = '\0';
    hash_add(table, "digest-uri", value);
    
    /* generate response */

    /* construct MD5(node : realm : password) */
    MD5Init(&MD5);
    MD5Update(&MD5, (unsigned char *)node, strlen(node));
    MD5Update(&MD5, (unsigned char *)":", 1);
    MD5Update(&MD5, (unsigned char *)realm, strlen(realm));
    MD5Update(&MD5, (unsigned char *)":", 1);
    MD5Update(&MD5, (unsigned char *)password, strlen(password));
    MD5Final(digest, &MD5);

    /* digest now contains the first field of A1 */

    MD5Init(&MD5);
    MD5Update(&MD5, digest, 16);
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "nonce");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "cnonce");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Final(digest, &MD5);

    /* now digest is MD5(A1) */
    memcpy(HA1, digest, 16);

    /* construct MD5(A2) */
    MD5Init(&MD5);
    MD5Update(&MD5, (unsigned char *)"AUTHENTICATE:", 13);
    value = hash_get(table, "digest-uri");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    if (strcmp(hash_get(table, "qop"), "auth") != 0) {
	MD5Update(&MD5, (unsigned char *)":00000000000000000000000000000000",
		  33);
    }
    MD5Final(digest, &MD5);

    memcpy(HA2, digest, 16);

    /* construct response */
    MD5Init(&MD5);
    _digest_to_hex((char *)HA1, hex);
    MD5Update(&MD5, (unsigned char *)hex, 32);
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "nonce");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "nc");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "cnonce");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Update(&MD5, (unsigned char *)":", 1);
    value = hash_get(table, "qop");
    MD5Update(&MD5, (unsigned char *)value, strlen(value));
    MD5Update(&MD5, (unsigned char *)":", 1);
    _digest_to_hex((char *)HA2, hex);
    MD5Update(&MD5, (unsigned char *)hex, 32);
    MD5Final(digest, &MD5);

    response = xmpp_alloc(ctx, 32+1);
    _digest_to_hex((char *)digest, hex);
    memcpy(response, hex, 32);
    response[32] = '\0';
    hash_add(table, "response", response);

    /* construct reply */
    result = NULL;
    rlen = 0;
    result = _add_key(ctx, table, "username", result, &rlen, 1); 
    result = _add_key(ctx, table, "realm", result, &rlen, 1); 
    result = _add_key(ctx, table, "nonce", result, &rlen, 1); 
    result = _add_key(ctx, table, "cnonce", result, &rlen, 1); 
    result = _add_key(ctx, table, "nc", result, &rlen, 0); 
    result = _add_key(ctx, table, "qop", result, &rlen, 0); 
    result = _add_key(ctx, table, "digest-uri", result, &rlen, 1); 
    result = _add_key(ctx, table, "response", result, &rlen, 0); 
    result = _add_key(ctx, table, "charset", result, &rlen, 0);
 
    xmpp_free(ctx, node);
    xmpp_free(ctx, domain);
    hash_release(table); /* also frees value strings */

    /* reuse response for the base64 encode of our result */
    response = base64_encode(ctx, (unsigned char *)result, strlen(result));
    xmpp_free(ctx, result);

    return response;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rcx, %r15
movq %rdx, %r12
movq %rsi, %r14
movq %rdi, %rbx
movq %rsi, %rdi
callq 0x2180
movq %rbx, %rdi
movq %r14, %rsi
movl %eax, %edx
callq 0x84fb
testq %rax, %rax
je 0x7c29
movq %rax, %r13
leaq -0x281a(%rip), %rdx     # 0x5263
movq %rbx, %rdi
movl $0xa, %esi
callq 0x649c
testq %rax, %rax
je 0x7c43
movq %rax, %r14
movq %r15, 0x58(%rsp)
movq %r13, 0x10(%rsp)
movb (%r13), %al
testb %al, %al
je 0x7c7f
movq 0x10(%rsp), %rbp
cmpb $0x20, %al
je 0x7abd
movzbl %al, %ecx
cmpl $0x2c, %ecx
jne 0x7ac5
movb 0x1(%rbp), %al
incq %rbp
jmp 0x7ab1
leaq 0x1(%rbp), %r13
xorl %r15d, %r15d
testb %al, %al
je 0x7c7f
movzbl %al, %eax
cmpl $0x3d, %eax
je 0x7ae9
movb 0x1(%rbp,%r15), %al
incq %r15
incq %r13
jmp 0x7acc
leal 0x1(%r15), %esi
movq %rbx, %rdi
callq 0x5251
testq %rax, %rax
je 0x7c7f
movq %r14, 0x8(%rsp)
movq %r12, (%rsp)
movl %r15d, %r12d
movq %rax, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movq %rax, %r14
callq 0x2050
movq %r14, 0x18(%rsp)
movb $0x0, (%r14,%r12)
leaq (%r15,%rbp), %rcx
incq %rcx
movzbl (%rcx), %eax
cmpl $0x22, %eax
je 0x7b39
cmpl $0x27, %eax
jne 0x7ba7
movq %rcx, 0x50(%rsp)
addq %r15, %rbp
addq $0x2, %rbp
movq $-0x1, %r15
movb 0x1(%r13), %cl
incq %r13
incq %r15
cmpb %al, %cl
je 0x7b5e
testb %cl, %cl
jne 0x7b4c
leal 0x1(%r15), %esi
movq %rbx, %rdi
callq 0x5251
testq %rax, %rax
movq 0x8(%rsp), %r14
je 0x7c6e
movq %rax, %r12
movq %rbp, %rsi
movl %r15d, %ebp
movq %rax, %rdi
movq %rbp, %rdx
callq 0x2050
movb $0x0, (%r12,%rbp)
movb (%r13), %al
xorl %ebp, %ebp
movq 0x50(%rsp), %rcx
cmpb (%rcx), %al
sete %bpl
addq %r13, %rbp
jmp 0x7bfa
xorl %r15d, %r15d
movq %rcx, %rbp
movq 0x8(%rsp), %r14
testb %al, %al
je 0x7bc9
movzbl %al, %eax
cmpl $0x2c, %eax
je 0x7bc9
movb 0x1(%rbp), %al
incq %rbp
incq %r15
jmp 0x7bb2
movq %rcx, %r13
leal 0x1(%r15), %esi
movq %rbx, %rdi
callq 0x5251
testq %rax, %rax
je 0x7c6e
movq %rax, %r12
movl %r15d, %r15d
movq %rax, %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0x2050
movb $0x0, (%r12,%r15)
movq %r14, %rdi
movq 0x18(%rsp), %r15
movq %r15, %rsi
movq %r12, %rdx
callq 0x65bd
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5263
movb (%rbp), %al
testb %al, %al
movq (%rsp), %r12
jne 0x7ab1
jmp 0x7c7f
leaq 0x6196(%rip), %rsi      # 0xddc6
leaq 0x6227(%rip), %rdx      # 0xde5e
movq %rbx, %rdi
xorl %eax, %eax
callq 0x536c
jmp 0x7c4e
movq %rbx, %rdi
movq %r13, %rsi
callq 0x5263
leaq 0x6171(%rip), %rsi      # 0xddc6
leaq 0x616f(%rip), %rdx      # 0xddcb
xorl %r14d, %r14d
movq %rbx, %rdi
xorl %eax, %eax
callq 0x536c
jmp 0x82bb
movq %rbx, %rdi
movq 0x18(%rsp), %rsi
callq 0x5263
movq (%rsp), %r12
movq %rbx, %rdi
movq 0x10(%rsp), %rsi
callq 0x5263
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6a0e
movq %rax, %rbp
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6a66
movq %rax, %r13
leaq 0x613c(%rip), %rsi      # 0xddeb
movq %r14, %rdi
callq 0x6766
testq %rax, %rax
je 0x7cc1
cmpb $0x0, (%rax)
jne 0x7cec
movq %rbx, %rdi
movq %r13, %rsi
callq 0xc0d0
leaq 0x6118(%rip), %r15      # 0xddeb
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x65bd
movq %r14, %rdi
movq %r15, %rsi
callq 0x6766
movq %rax, (%rsp)
movq %rbx, %rdi
movq %rbp, %rsi
callq 0xc0d0
leaq 0x580f(%rip), %rsi      # 0xd511
movq %r14, %rdi
movq %rax, %rdx
callq 0x65bd
leaq 0x60e4(%rip), %rsi      # 0xddf8
movq %rbx, %rdi
callq 0xc0d0
leaq 0x60ce(%rip), %rsi      # 0xddf1
movq %r14, %rdi
movq %rax, %rdx
callq 0x65bd
leaq 0x60d3(%rip), %rsi      # 0xde08
movq %rbx, %rdi
callq 0xc0d0
leaq 0x60c1(%rip), %rsi      # 0xde05
movq %r14, %rdi
movq %rax, %rdx
callq 0x65bd
leaq 0x57b6(%rip), %rsi      # 0xd50c
movq %rbx, %rdi
callq 0xc0d0
leaq 0x60ac(%rip), %rsi      # 0xde11
movq %r14, %rdi
movq %rax, %rdx
callq 0x65bd
movq %r13, %rdi
callq 0x2180
leaq 0x6(%rax), %rsi
movq %rbx, %rdi
callq 0x5251
movq %rax, %r15
movl $0x70706d78, (%rax)     # imm = 0x70706D78
movb $0x2f, 0x4(%rax)
leaq 0x5(%rax), %r12
movq %r13, %rdi
callq 0x2180
movq %r12, %rdi
movq %r13, %rsi
movq %rax, %rdx
callq 0x2050
movq %r13, 0x8(%rsp)
movq %r13, %rdi
callq 0x2180
movb $0x0, 0x5(%r15,%rax)
leaq 0x6056(%rip), %rsi      # 0xde1b
movq %r14, %rdi
movq %r15, %rdx
callq 0x65bd
leaq 0x80(%rsp), %r13
movq %r13, %rdi
callq 0x6b54
movq %rbp, %rdi
callq 0x2180
movq %r13, %rdi
movq %rbp, 0x10(%rsp)
movq %rbp, %rsi
movl %eax, %edx
callq 0x6b7a
leaq 0x536e(%rip), %r15      # 0xd16f
movq %r13, %rdi
movq %r15, %rsi
movl $0x1, %edx
callq 0x6b7a
movq (%rsp), %r12
movq %r12, %rdi
callq 0x2180
movq %r13, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6b7a
movq %r13, %rdi
movq %r15, %rsi
movl $0x1, %edx
callq 0x6b7a
movq 0x58(%rsp), %r12
movq %r12, %rdi
callq 0x2180
movq %r13, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6b7a
leaq 0x40(%rsp), %rbp
movq %rbp, %rdi
movq %r13, %rsi
callq 0x73f6
movq %r13, %rdi
callq 0x6b54
movq %r13, %rdi
movq %rbp, %rsi
movl $0x10, %edx
callq 0x6b7a
movq %r13, %rdi
movq %r15, %rsi
movl $0x1, %edx
callq 0x6b7a
leaq 0x5f5f(%rip), %rsi      # 0xddf2
movq %r14, %rdi
callq 0x6766
movq %rax, %r12
movq %rax, %rdi
callq 0x2180
movq %r13, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6b7a
movq %r13, %rdi
movq %r15, %rsi
movl $0x1, %edx
callq 0x6b7a
movq %r14, %rdi
leaq 0x5f24(%rip), %rsi      # 0xddf1
callq 0x6766
movq %rax, %r15
movq %rax, %rdi
callq 0x2180
movq %r13, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x6b7a
movq %rbp, %rdi
movq %r13, %rsi
callq 0x73f6
movaps (%rbp), %xmm0
movaps %xmm0, 0x70(%rsp)
movq %r13, %rdi
callq 0x6b54
leaq 0x5f19(%rip), %rsi      # 0xde26
movq %r13, %rdi
movl $0xd, %edx
callq 0x6b7a
movq %r14, %rdi
leaq 0x5ef7(%rip), %rsi      # 0xde1b
callq 0x6766
movq %rax, %r15
movq %rax, %rdi
callq 0x2180
movq %r13, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x6b7a
movq %r14, %rdi
leaq 0x5ec6(%rip), %rsi      # 0xde11
callq 0x6766
movq %rax, %rdi
leaq 0x55b2(%rip), %rsi      # 0xd50c
callq 0x22e0
testl %eax, %eax
je 0x7f7c
leaq 0x5eca(%rip), %rsi      # 0xde34
leaq 0x80(%rsp), %rdi
movl $0x21, %edx
callq 0x6b7a
leaq 0x40(%rsp), %r15
leaq 0x80(%rsp), %r12
movq %r15, %rdi
movq %r12, %rsi
callq 0x73f6
movaps (%r15), %xmm0
movaps %xmm0, 0x60(%rsp)
movq %r12, %rdi
callq 0x6b54
xorl %eax, %eax
leaq 0x6052(%rip), %rbp      # 0xe000
movzbl 0x70(%rsp,%rax), %ecx
movl %ecx, %edx
shrl $0x4, %edx
movb (%rdx,%rbp), %dl
movb %dl, 0x20(%rsp,%rax,2)
andl $0xf, %ecx
movb (%rcx,%rbp), %cl
movb %cl, 0x21(%rsp,%rax,2)
incq %rax
cmpq $0x10, %rax
jne 0x7fae
leaq 0x80(%rsp), %r15
leaq 0x20(%rsp), %rsi
movq %r15, %rdi
movl $0x20, %edx
callq 0x6b7a
leaq 0x517c(%rip), %r13      # 0xd16f
movq %r15, %rdi
movq %r13, %rsi
movl $0x1, %edx
callq 0x6b7a
leaq 0x5de8(%rip), %rsi      # 0xddf2
movq %r14, %rdi
callq 0x6766
movq %rax, %r12
movq %rax, %rdi
callq 0x2180
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6b7a
movq %r15, %rdi
movq %r13, %rsi
movl $0x1, %edx
callq 0x6b7a
leaq 0x5dc4(%rip), %rsi      # 0xde05
movq %r14, %rdi
callq 0x6766
movq %rax, %r12
movq %rax, %rdi
callq 0x2180
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6b7a
movq %r15, %rdi
movq %r13, %rsi
movl $0x1, %edx
callq 0x6b7a
leaq 0x5d79(%rip), %rsi      # 0xddf1
movq %r14, %rdi
callq 0x6766
movq %rax, %r12
movq %rax, %rdi
callq 0x2180
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6b7a
movq %r15, %rdi
movq %r13, %rsi
movl $0x1, %edx
callq 0x6b7a
leaq 0x5d62(%rip), %rsi      # 0xde11
movq %r14, %rdi
callq 0x6766
movq %rax, %r12
movq %rax, %rdi
callq 0x2180
movq %r15, %rdi
movq %r12, %rsi
movl %eax, %edx
callq 0x6b7a
movq %r15, %rdi
movq %r13, %rsi
movl $0x1, %edx
callq 0x6b7a
xorl %eax, %eax
movzbl 0x60(%rsp,%rax), %ecx
movl %ecx, %edx
shrl $0x4, %edx
movb (%rdx,%rbp), %dl
movb %dl, 0x20(%rsp,%rax,2)
andl $0xf, %ecx
movb (%rcx,%rbp), %cl
movb %cl, 0x21(%rsp,%rax,2)
incq %rax
cmpq $0x10, %rax
jne 0x80e1
leaq 0x80(%rsp), %r15
leaq 0x20(%rsp), %rsi
movq %r15, %rdi
movl $0x20, %edx
callq 0x6b7a
leaq 0x40(%rsp), %rdi
movq %r15, %rsi
callq 0x73f6
movl $0x21, %esi
movq %rbx, %rdi
callq 0x5251
xorl %ecx, %ecx
movq 0x10(%rsp), %r12
movq 0x8(%rsp), %r13
movzbl 0x40(%rsp,%rcx), %edx
movl %edx, %esi
shrl $0x4, %esi
movb (%rsi,%rbp), %sil
movb %sil, 0x20(%rsp,%rcx,2)
andl $0xf, %edx
movb (%rdx,%rbp), %dl
movb %dl, 0x21(%rsp,%rcx,2)
incq %rcx
cmpq $0x10, %rcx
jne 0x8145
movaps 0x20(%rsp), %xmm0
movaps 0x30(%rsp), %xmm1
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
movb $0x0, 0x20(%rax)
leaq 0x5693(%rip), %r15      # 0xd81a
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x65bd
leaq 0x5375(%rip), %rdx      # 0xd511
movq %rbx, %rdi
movq %r14, %rsi
xorl %ecx, %ecx
movl $0x1, %r8d
callq 0x82d0
leaq 0x5c35(%rip), %rdx      # 0xddeb
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
movl $0x1, %r8d
callq 0x82d0
leaq 0x5c21(%rip), %rdx      # 0xddf2
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
movl $0x1, %r8d
callq 0x82d0
leaq 0x5c05(%rip), %rdx      # 0xddf1
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
movl $0x1, %r8d
callq 0x82d0
leaq 0x5bfe(%rip), %rdx      # 0xde05
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x82d0
leaq 0x5bf2(%rip), %rdx      # 0xde11
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x82d0
leaq 0x5be4(%rip), %rdx      # 0xde1b
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
movl $0x1, %r8d
callq 0x82d0
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x82d0
leaq 0x5bf0(%rip), %rdx      # 0xde56
movq %rbx, %rdi
movq %r14, %rsi
movq %rax, %rcx
xorl %r8d, %r8d
callq 0x82d0
movq %rax, %r15
movq %rbx, %rdi
movq %r12, %rsi
callq 0x5263
movq %rbx, %rdi
movq %r13, %rsi
callq 0x5263
movq %r14, %rdi
callq 0x651f
movq %r15, %rdi
callq 0x2180
movq %rbx, %rdi
movq %r15, %rsi
movl %eax, %edx
callq 0x78e8
movq %rax, %r14
movq %rbx, %rdi
movq %r15, %rsi
callq 0x5263
movq %r14, %rax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq